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

CoCreateInstance: Create a COM instance defined in a .NET library?

本文关键字:定义 COM 实例 创建 NET CoCreateInstance      更新时间:2023-10-16

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

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

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

然后:

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

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

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

在C++中创建COM客户端的另一种方法是Microsoft特定的#import指令,但我不确定它是否与.基于 NET 的组件。如果可以为 .NET 组件创建 .tlb 文件,则只需添加所需的内容,如下所示:

#import "MyLibrary.tlb"

该指令有很多选择。有关详细信息,请查看此 MSDN 文章。