简体   繁体   English

从非托管代码中获取COM对象

[英]Obtaining COM objects from unmanaged code

I have a library that exports an unmanaged C routine that returns pointers to COM IUnknown-based objects. 我有一个库,导出一个非托管的C例程,返回指向基于COM IUnknown的对象的指针。 The DLL is not registered, and is not server. DLL未注册,也不是服务器。 I would like to use the COM types from C#. 我想使用C#中的COM类型。

I have already written C# interfaces for the COM types. 我已经为COM类型编写了C#接口。 What is the C# equivalent of calling LoadLibrary() and GetProcAddress()? 什么是调用LoadLibrary()和GetProcAddress()的C#等价物? How would I call the result of GetProcAddress() and then call it to load a COM interface pointer? 我如何调用GetProcAddress()的结果然后调用它来加载COM接口指针?

Here is a snippet of C++ that illustrates what I am after: 这是一个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);

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

You just need to use interop to describe your GetFactory function, something like this 您只需要使用互操作来描述您的GetFactory函数,就像这样

[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 强制转换等同于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. 您需要将C ++接口定义复制为C#接口定义,可能需要使用[marshalas]属性。 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. COM iterop代码似乎有一个强烈的假设,即所有COM方法都返回HRESULT,如果你在那里使用流程,那么编组工作会更简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM