1

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

4

2 回答 2

2

事实证明,我是对的,类的 UUID 就在那里,但得到它是我没想到的:

struct __declspec(uuid("45b50f1e-d551-4be0-b52a-7ec075840114")) Cls;

然后:

HRESULT hr = ::CoCreateInstance(__uuidof(Cls), 
                                NULL, 
                                CLSCTX_INPROC_SERVER, 
                                __uuidof(IFoo), 
                               (void**)&pUnk);

这解决了问题并正常工作。

于 2012-05-02T02:13:34.510 回答
1

只需使用MIDL将您的 IDL 文件编译成一组 C++ 文件并将它们包含到您的 C++ 程序中。请记住,接口不是“入口点”,您也将需要 IDL 中的类对象。

在 C++ 中创建 COM 客户端的另一种方法是 Microsoft 特定#import指令,但我不确定它是否与基于 .NET 的组件兼容。如果你可以为你的 .NET 组件创建一个 .tlb 文件,你可以像这样添加需要的东西:

#import "MyLibrary.tlb"

该指令有很多选项。查看此MSDN 文章了解详细信息。

于 2012-05-02T02:12:46.613 回答