CoCreateInstance:创建.NET库中定义的COM实例?

时间:2012-05-02 01:35:06

标签: c++ .net com com-interop

我创建了一个在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

2 个答案:

答案 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