c# - 从非托管代码获取 COM 对象

标签 c# com managed

我有一个库,它导出一个非托管 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/

相关文章:

c++ - CoCreateInstance 失败,错误为 "System can not find the file specified"

c# - 如何在 C# 中编码(marshal)指向一系列以 null 结尾的字符串的指针?

c# - C++/CLI 中指向托管数组的指针

c# - 提供接口(interface)的实现以供 Moq 使用

c# - 日志记录仅在本地有效,但在部署到 Microsoft Azure 应用服务时无效

c# - 这个自引用继承代码中发生了什么?

c# - 如何使我的 C# DLL 成为自注册 dll

c# - 如何根据年份获取一个月中的总天数?

c# - 如何在 COM 中传递 RECT

jsf - 在另一个托管 bean 中获取托管 bean 引用