COM: Getting GUID of coclass object using pointer to interface it implements - c++

Having pointer to COM interface that are implemented by some concrete component class object is it possible to get a GUID of the underlying object that implements this interface (CLSID)?
Update 1
More generally, I have a function like SetFont(ICanvasFont* font) and I need a way to determine if the underlying object that implements the ICanvasFont interface is of a certain class (say MCanvasFont).

IUnknown::QueryInterface on this interface pointer to obtain one of the following: IPersist, IPersistStream, IPersistStreamInit or other IPersist* interfaces. If you are lucky to get one, then GetClassID method will get you the CLSID class identifier (alternate option is IProvideClassInfo and IProvideClassInfo::GetClassInfo).
Note that this kind of information does not have to exist. An interface pointer can be valid without having CLSID on the class implementing it.
UPD. If the main goal is to recognize your own implementation on the provided interface ("Is the provided ICanvasFont the instance of my own MCanvasFont class, or it is something different?"), then the easiest yet efficient way is to implement some extra private interface on the class. If your querying it succeeds, then you recognize the instance. Provided no marshaling takes place, you can possibly even static_cast back to original C++ pointer.

Related

Convert from a Base object to a Derived object in C++

I am trying to abstract sections of code to be platform independent.
I have one section of code that is creating objects of Base class IModel.
std::shared_ptr<IModel> joint_model_3d = std::make_shared<IModel>();
I have another section of code that is responsible for rendering. In order to render the object I need to convert it to the derived class Direct3DModel
class Direct3DModel : public IModel
I know that I can do a dynamic_cast from Direct3DModel to IModel for sections of code that are platform independent, and then dynamic_cast back into Direct3DModel for rendering.
My question is, can I create an object of the Base class IModel in the platform independent code, which is not supposed to know Direct3DModel, and convert it to Direct3DModel when I need it for rendering.
Would I need some kind of object creator class that is not platform independent for this?
My question is, can I create an object of the Base class IModel in the platform independent code, which is not supposed to know Direct3DModel, and convert it to Direct3DModel when I need it for rendering.
No, that won't work.
You'll have to create a Direct3DModel object in the code base that knows about the class. The platform independent code needs to call the platform dependent code to construct such an object. You may use the Factory Pattern to implement the functionality.
The platform independent code will have to work with base class pointers and references (IModel in your case). As long as the pointer/reference points to a Direct3DModel object, you may use dynamic_cast in the platform-specific code to get a pointer/reference to the Direct3DModel to proceed with the platform-specific logic.
Would I need some kind of object creator class that is not platform independent for this?
Yes. The Factory Pattern facilitates that.

Performing "true" dynamic casts at runtime?

So I am still working on a flexible scripting system for this school project and have come to a road block. The problem is this: I have a script state manager interface that any scripting state will implement (currently implementing lua, but want to be able to add python later). It has pure virtual functions for things such as DoFile, DoString, RegisterObject and RegisterFunction. So the LuaStateManager implements this interface using luaplus classes and encapsulates the LuaState object as it should.
So when an object registers itself with lua and throws all its methods into a metatable I have to do something like this:
metaTable.RegisterObjectDirect(“Move”, (Actor*)0, &Actor::Move);
This would be fine if I had access to the underlying state object in the StateManager interface as it would be getting called from the Actor class itself so the cast could be guaranteed. Unfortunately, I need to somehow pass this info to the LuaState::RegisterFunction method so the I don't have to expose the LuaState object and couple my classes to it. As far as I can see though, there is no way to pass information about which type of class to cast to.
Does any body have any suggestions? I thought about trying to use a templated function to perform the cast, but I know that you can't have function pointers to templates, so that is out the window. Thanks!

Late Binding COM objects with C++Builder

We're interfacing to some 3rd party COM objects from a C++Builder 2010 application.
Currently we import the type library and generate component wrappers, and then are able to make method calls and access properties in a fairly natural way.
object->myProperty = 42;
object->doSomething(666);
However, we've been bitten by changes to the COM object's interface (which is still being extended and developed) causing our own app to fail because some method GUIDs seem to get invalidated - even if the only change to the interface has been the addition of a new method).
Late Binding has been suggested as a way of addressing this. I think this requires our code to be changed rather like this:
object.OlePropertySet("myProperty", 42);
object.OlePrcedure("doSomething", 666);
Obviously this is painful to read and write, so we'd have to write wrapper classes instead.
Is there any way of getting late binding wrappers generated automatically when we import the type library? And, if so, are they smart enough to only do the textual binding once when the object is created, rather than on every single method call?
When you import a TypeLibrary for a COM object that supports late-binding (when it implements the IDispatch interface), the importer can generate separate wrapper classes (not components) for both static-binding and late-binding.
Adding a new method to an existing interface should not invalidate your code. Methods do not have GUIDs. However, for an IDispatch-based interface, its methods do have DISPID values associated with them, and those DISPID values can be changed from one release to another. Though any respectable COM developer should never do that once an interface definition has been locked in.
After deep investigation of the code and headers generated by the TLIBIMP, this turns out to be fairly easy.
If your Type Library has a class Foo, then after importing the type library, you would typically use the auto-generated smart pointer classes IFooPtr.
{
IFooPtr f;
...
f->myMethod(1,2);
}
You should note that at this point that the bindings are static - that is, they depend not just on the GUIDs of the objects and the DISPIDs of the methods, but on the exact layout of the VTable in the DLL. Any changes that affect the vtable - for instance, adding an additional method to a base class of Foo will cause the method call to fail.
To use dynamic bindings, you can use the IFooDisp classes instead of IFooPtr. Again, these are smart wrappers, handling object lifetimes automatically. Note that with these classes you should use the . operator to access methods, not the indirection -> operator. Using the indirection operator will call the method, but via a static binding.
{
IFooDisp f;
...
f.myMethod(1,2);
}
By using these IDispatch-based wrappers, methods will be dispatched by their DISPIDs, even if the objects vtable layout is changed. I think these classes also give a way to dispatch by function name rather than DISPID, but haven't confirmed the details of that.

Using coclass that implements multiple interfaces

I am writing a C++/CLI application that makes use of a COM dll that provides a number of classes. Most of them implement a number of interfaces. I was wondering how I can access the methods of each of the various interfaces. For instance when I look at the type library one of the classes is defined as:
coclass FWFile {
[default] interface IFWFile;
interface _IFWFileInternal;
[default, source] interface _FWFileEvents;
interface CStatistics;
interface IFWFile2;
interface IFWFile3;
interface IFWFile4;
};
When I create an object of this type it appears to implement the IFWFile interface. However, I want to make use of the methods in IFWFile2. Can I simply create an object of type IFWFile2 and cast it?
IFWFile2 file2 = (IFWFile2)file1;
When using CoCreateInstance() you can specify which interface to retrieve from the newly created object. If you want more than one interface - retrieve one when calling CoCreateInstance() and use QueryInterface() to retrieve the other interfaces. Don't forget to have Release() called for each successful interface retrieval.
Just don't C-style cast COM pointers - interfaces are not guaranteed to be in the order specified in the type library and the actual class is not guaranteed to actually have the interface implemented. Always use QueryInterface() to retrieve interface pointers from COM objects.

How should I create classes in ATL project?

I'm writing an ATL project and I wonder how should I create classes here.
Right now I have one class created by Add/Class/ATL Simple Object. I want to divide it to smaller classes but method from this classes should use CComPtr and have CComPtr as an argument. I can't create 'simple' c++ class because I don't have CComPtr there.
Should I create ATL classes by ATL Simple Object Wizard and then use interface for this class to call methods. Like here:
CComPtr<ITestAtlClass> tptr;
tptr.CoCreateInstance(CLSID_TestAtlClass);
tptr->test();
And should I add all public methods by Class View/ITestAtlClass/Add/Add Method?
What about constructors? Do I must initialize my class only by properties (and add them by Class View/ITestAtlClass/Add/Add Property)? And pass every com object by IUnknown interface?
Can somebody tell me how it should be done in ATL project. I will use this smaller classes internally (nobody will create this classes outside my DLL) just to make my code more readable.
I don't understand your comment that you can't use CComPtr from a simple C++ class. Can you please clarify?
I see two strategies:
build a clean C++ object model that solves the problem, and then wrap it in a thin facade layer of one or more COM objects
Use ATL classes throughout, and use CComObject<> and derivatives to instantiate and maintain these without the overhead of CoCreateInstance and the limitations of only using public interfaces.
The first one is usually much nicer, but if you're building a data-heavy object model, the second can be a useful technique.
If you have an ATL COM class called CVehicle, that derives from CComObjectRootEx<> and friends, you can instantiate it like so;
CComObject<CVehicle>* vehicle = NULL;
CComObject<CVehicle>::CreateInstance(&vehicle);
vehicle->AddRef();
// To get at any of its interfaces, use:
CComPtr<ICar> car = 0;
vehicle->QueryInterface(&car);
// And to delete object, use:
vehicle->Release();
There's also variations on CComObject<>, e.g. CComObjectStack<> that use different allocation and reference counting strategies.
As you can see, this is pretty messy. If you can explain what you mean by your comment on not being able to use CComPtr, maybe I can expand on that.