能否从非托管的C++调用托管DLL?

8

是否可以从非托管的C++代码中调用CLR DLL(例如使用C#编写的DLL)?

我需要一个非托管的DLL来调用它,也许甚至可以通过使用C++ / CLI构建的某些代理C++进程来实现?


2
你可以将那个托管的dll封装成一个可执行文件,它是一个控制台应用程序并接受命令行参数,同时将其结果输出到stdout。然后你可以像调用其他exe一样调用它。虽然不是理想的解决方案,但可能会起作用。我希望你没有使用多线程,因为我不知道这是否会起作用。 - Hamish Grubijan
1
你已经给出了答案。用C++/CLI(或C++.Net或managed C++或者它今天被称为什么)编写一个代理,然后从未管理的C++代码中调用此代理。 - Patrick
也许这可以帮助:https://dev59.com/6HNA5IYBdhLWcg3wL6ux - smerlin
3个回答

6

CLR DLL必须构建为可见的COM程序集。如果你控制C#,那么重新构建很简单,否则直接使用几乎不可能。


添加了“直接使用它”的内容。否则意思会有误,抱歉。 - SWeko
@SWeko:总有反向 PInvoke 的方法,所以这并不是不可能的。 - Aamir
据我所知,要使用反向 PInvoke,您仍然需要访问 C# 代码以设置委托和调用约定(我从未使用过,因此无法从经验上说)。 - SWeko

5
@SWeko提供了最佳答案,如果您可以修改原始DLL并且您的非托管代码可以依赖于访问COM公寓(使用::CoInitialize()调用其自己的线程或非托管代码的调用线程具有一致的公寓),那么这种方法是最佳的。
如果不是这种情况,则最好的解决方案是创建一个“托管”的C++ DLL作为托管C#程序集的包装器。这称为C++/CLI。您可以公开非托管C API操作,并在这些操作的实现内部委托给托管API。它运行得非常好,与调用COM API不同,不存在线程亲和性问题。

4
我不确定是否适用,但也许"Reverse PInvoke"是一个选项。
如果您首先从C#调用到C++,则可以向C++提供 .net 委托,使其能够用作函数指针。 然后可以使用该函数指针从C++调用到C#。
public delegate int Read(int target);
[DllImport("yourC++.dll")]
static extern void RegisterRead(Read x);
Read m_Read = new Read(yourClass.Read);

RegisterRead(m_Read);

GC收集委托时可能存在一些技巧,如果只是在RegisterRead中立即使用,则具有委托的任何类都可能需要固定。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接