COM:使用指向它实现的接口的指针获取 coclass 对象的 GUID

2022-01-14 00:00:00 com c++

拥有指向由某个具体组件类对象实现的 COM 接口的指针,是否可以获得实现该接口的底层对象的 GUID (CLSID)?

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)?

更一般地说,我有一个类似 SetFont(ICanvasFont* font) 的函数,我需要一种方法来确定实现 ICanvasFont 接口的底层对象是否属于某些类(比如 MCanvasFont).

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 在此接口指针上获取以下之一:IPersist, IPersistStreamIPersistStreamInit 或其他IPersist* 接口.如果你幸运地得到了一个,那么 GetClassID 方法将为你获取 CLSID 类标识符(替代选项是 IProvideClassInfoIProvideClassInfo::GetClassInfo).

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).

请注意,此类信息不必存在.接口指针在实现它的类上没有 CLSID 也可以是有效的.

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.如果主要目标是在提供的接口上识别您自己的实现(提供的 ICanvasFont 是我自己的 MCanvasFont 类的实例,还是有所不同?"),那么最简单但有效的方法是在类上实现一些额外的私有接口.如果您的查询成功,那么您可以识别该实例.如果不进行封送处理,您甚至可以 static_cast 回到原始 C++ 指针.

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.

相关文章