4

我有一个库,它导出一个非托管 C 例程,该例程返回指向基于 COM IUnknown 的对象的指针。DLL 未注册,也不是服务器。我想使用 C# 中的 COM 类型。

我已经为 COM 类型编写了 C# 接口。调用 LoadLibrary() 和 GetProcAddress() 的 C# 等效项是什么?如何调用 GetProcAddress() 的结果,然后调用它来加载 COM 接口指针?

这是一个 C++ 片段,它说明了我所追求的:

// Assume I have previously declared IMyType
HANDLE mylib = ::LoadLibrary("myfakecom.dll");
IUnknown* (*GetterFunc) getter;
getter = (GetterFunc)::GetProcAddress(mylib, "GetFactory");
IUnknown *unk = getter();
IMyType *mytype = unk->QueryInterface(IID_MYTYPE);

我的直觉说“用 C++/CLI 来做”,尽管我不确定如何对任何泛型类型执行此操作,以及如何将原始 IUnknown 指针强制转换为我将使用 [Guid] 属性声明的管理器指针类型在托管接口上。

4

1 回答 1

2

您只需要使用互操作来描述您的GetFactory功能,就像这样

[DllImport("myfakecom.dll")]
[return: MarshalAs(UnmanagedType.IUnknown)]
static extern object GetFactory();

然后,一旦您在托管代码中拥有该对象。强制转换相当于 QueryInterface

void Foo(Object unk)
{
    IMyType mytype = (IMyType)unk;
} 

您需要将 C++ 接口定义复制为 C# 接口定义,可能带有 [marshalas] 属性。但既然你已经这样做了,剩下的应该很容易。

我建议您将工厂原型从

IUnknown * GetFactory();

HRESULT GetFactory([out] IUnknown ** ppunk);

COM iterop 代码似乎有一个强烈的假设,即所有 COM 方法都返回 HRESULT,如果您按照流程进行操作,那么让编组工作会更简单。

于 2010-01-29T06:25:28.750 回答