本机 C++ 通过代理 C++ 托管 dll 使用 C# dll
Posted
技术标签:
【中文标题】本机 C++ 通过代理 C++ 托管 dll 使用 C# dll【英文标题】:Native C++ use C# dll via proxy C++ managed dll 【发布时间】:2012-07-02 04:23:25 【问题描述】:这是相当复杂的,所以请耐心等待。我有一个用本机(仅限 Win32)C++ 编码的第 3 方程序(“目标”)。作为目标设计的一部分,它实现了一个 dll 插件系统。本地 DLL 当放置在程序的“ext”目录中时,由目标加载。然后目标调用每个 DLL 提供的四种方法(Initialize、SendHook、RecvHook、Terminate)。正如您可能从函数名称中猜到的那样,加载项挂钩目标中的某些函数。我没有目标的源代码。
其中一个插件陈旧且有缺陷 - 更不用说令人困惑且相当丑陋。它是用 Delphi 编写的(当然,编译为 win32 DLL)。在过去的几周里,我一直在增强插件并将其翻译为 C#(我将其称为“扩展”)。现在已经完成,所以我将注意力转向让目标加载扩展(构建为类库)。
显然,目标(本机 C++)无法直接加载扩展(托管 C#)。因此,在研究之后,似乎我只需要一个“代理”DLL(用 VC++ 编写并支持 CLR)来加载我的扩展,然后负责将方法调用从目标传递到扩展。
“简单。”是的,对。我现在比吃吃喝玩乐袋里的变色龙还要困惑。我已经看到有关使用 COM 的东西,这绝对是我需要避免的,无论是在性能还是进程内存权限方面,因为扩展将调用一些方法(通过句柄传递给代理)。此外,我还看到了有关 tlb 和 #import 指令的内容。这似乎也不是正确的方法。
我看到这篇文章https://sites.google.com/site/srinivasnzd/csincppviacpp-cli 似乎终于走上了正轨。事实上,我可以从 C++ 代理调用我的托管 C# 就好了。作为奖励,__declspec(dllexport)
函数似乎(我还不能用实际目标测试它)可以通过代理适当地调用它们的托管对应物。但是现在问题已经开始出现了。
【问题讨论】:
我认为是那些在吃喝玩乐袋中寻找变色龙的人感到困惑。 可怜的变色龙不知道该变成什么颜色... 啊,我明白了。我想最后是我糊涂了。 这就是为什么我非常害怕 Win32 的古老语言。这也是为什么我们需要停止使用像 VB6 这样的语言和像 IE6 这样的程序。 如果有帮助,请查看filterdotnet.codeplex.com 并查看他如何设法将本机代码与托管代码链接起来。具体来说,查看源代码树中的native/clr.cpp
并查看CorBindToRuntimeEx
以及加载CLR 的相关方法。 IIRC 托管模块必须在 GAC 中,至少在这种情况下是这样。研究此代码应该可以帮助您至少回答一些问题,G/L。顺便说一句,在变色龙 n 吃喝玩乐的笑话里大声笑 :)
【参考方案1】:
查看此template 以在不使用 C++ 包装器的情况下导出 C# 代码的帮助。 不幸的是,开箱即用没有 DllExport 属性,因此您需要一个 C++ 包装器,或者您需要修改 IL 代码以执行导出。 编组地址没有问题,只需小心 C# 端的函数指针,因为您始终需要确保存在引用以使它们远离 GC 收集器。如果您保留静态引用,这是最简单的 - GC 在非托管代码中看不到对函数指针的引用,因此它可能会清理它。 如果您有多个 c# 模块,应用程序域将很重要 - 如果这些模块共享相同的代码,这将成为一个更大的问题。 exp来自链接器,ilk和lib与链接器相关,因此我希望您不需要复制它们,但在调试时可能需要它们。
【讨论】:
哇。我印象深刻...这与宣传的完全一样。但是,现在,每当我尝试让扩展加载表单(当然是在另一个线程上)时,目标都会冻结。根本没有错误消息......在我打开一个新问题之前有什么想法吗? 加载表单是什么意思? Windows 窗体? 是的,请看这里:***.com/questions/11304072/…以上是关于本机 C++ 通过代理 C++ 托管 dll 使用 C# dll的主要内容,如果未能解决你的问题,请参考以下文章
本机代码中的托管 dll(通过 com)。它是在进程中还是在进程 com 服务器中?