从非托管代码获取 COM 对象

发布于 2024-08-20 01:35:10 字数 647 浏览 8 评论 0原文

我有一个库,它导出一个非托管 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] 属性来声明管理器指针类型。

I have a library that exports an unmanaged C routine that returns pointers to COM IUnknown-based objects. The DLL is not registered, and is not server. I would like to use the COM types from C#.

I have already written C# interfaces for the COM types. What is the C# equivalent of calling LoadLibrary() and GetProcAddress()? How would I call the result of GetProcAddress() and then call it to load a COM interface pointer?

Here is a snippet of C++ that illustrates what I am after:

// 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);

My gut says "Do it with C++/CLI", though I am unsure of how I would do this for any generic type, and how I would coerce the raw IUnknown pointers into the manager pointer types I would declare using the [Guid] attributes on a managed interface.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我是男神闪亮亮 2024-08-27 01:35:10

您只需要使用互操作来描述您的 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,如果您按照那里的流程进行编组工作将会更简单。

You just need to use interop to describe your GetFactory function, something like this

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

Then once you have the object in managed code. A cast is the equivalent of QueryInterface

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

You will need to duplicate your C++ interface definitions as C# interface definitions, possibly with [marshalas] attributes. But since you have already done that, the rest should be easy.

I would suggest that you change your factory prototype from

IUnknown * GetFactory();

to

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

There seems to be a strong assumption by the COM iterop code that all COM methods return HRESULT and it will be simpler to get the marshalling to work if you go with the flow there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文