我有一个库,它导出一个非托管 C 例程,该例程返回指向基于 COM IUnknown 的对象的指针。 DLL 未注册,也不是服务器。我想使用 C# 中的 COM 类型。
我已经为 COM 类型编写了 C# 接口(interface)。调用 LoadLibrary() 和 GetProcAddress() 的 C# 等效项是什么?我如何调用 GetProcAddress() 的结果,然后调用它来加载 COM 接口(interface)指针?
这是一个 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] 托管接口(interface)上的属性。
最佳答案
您只需要使用互操作来描述您的 GetFactory
函数,就像这样
[DllImport("myfakecom.dll")]
[return: MarshalAs(UnmanagedType.IUnknown)]
static extern object GetFactory();
然后,一旦您在托管代码中拥有该对象。强制转换相当于 QueryInterface
void Foo(Object unk)
{
IMyType mytype = (IMyType)unk;
}
您需要将 C++ 接口(interface)定义复制为 C# 接口(interface)定义,可能带有 [marshalas] 属性。但既然你已经做到了,剩下的应该很容易。
我建议你改变你的工厂原型(prototype)
IUnknown * GetFactory();
到
HRESULT GetFactory([out] IUnknown ** ppunk);
COM 迭代操作代码似乎有一个强有力的假设,即所有 COM 方法都返回 HRESULT,如果按照那里的流程进行编码工作会更简单。
关于c# - 从非托管代码获取 COM 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2160184/