我创建了一个在IDL中定义的COM库,它有一个名为IFoo的“入口点”:
[
object,
uuid(789b4d46-4028-4196-8412-4c5c8ef86caa),
nonextensible,
pointer_default(unique)
]
interface IFoo: IUnknown
{
HRESULT HelloWorld();
};
我已经在我的C#库中实现了这一点:
[ComVisible(true)]
[Guid("45b50f1e-d551-4be0-b52a-7ec075840114")]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(IFoo))]
class Foo: IFoo
{
public void HelloWorld()
{
Console.WriteLine("Hello world");
}
}
我编译了这个,并将其注册为:
regasm.exe foo.dll
到目前为止,一切看起来都很好。
现在,如何在我的C ++程序中创建此实例?我认为正确的函数是:: CoCreateInstance:
::CoInitializeEx(NULL, COINIT_MULTITHREADED);
IUnknown *pUnk = 0;
HRESULT hr = ::CoCreateInstance(???,
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IFoo),
(void**)&pUnk);
这是创建此类实例的正确方法吗?如果是这样,那么“???”以上?
我认为该类的UUID(上面的“45b50f1e-d551-4be0-b52a-7ec075840114”)应该去那里,但我无法弄清楚如何从这个GUID字符串手动创建IID
答案 0 :(得分:2)
事实证明,我是对的,班级的UUID去了那里,但得到它是我没想到的:
struct __declspec(uuid("45b50f1e-d551-4be0-b52a-7ec075840114")) Cls;
然后:
HRESULT hr = ::CoCreateInstance(__uuidof(Cls),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IFoo),
(void**)&pUnk);
这解决了问题,并且工作正常。
答案 1 :(得分:1)
只需使用MIDL
将您的IDL文件编译成一组C ++文件,并将它们包含在您的C ++程序中。请记住,接口不是“入口点”,您也需要IDL中的类对象。
在C ++中创建COM客户端的另一种方法是Microsoft特定的#import
指令,但我不确定它是否与基于.NET的组件兼容。如果您可以为.NET组件创建.tlb文件,则可以添加如下所需的内容:
#import "MyLibrary.tlb"
该指令有很多选项。有关详细信息,请查看此MSDN article。