我有一个库,它导出一个非托管的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]属性。
答案 0 :(得分:1)
您只需使用互操作来描述您的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,如果你顺其自然,那么编组工作会更简单。