这是相当复杂的,所以请耐心等待。我有一个用本机(仅限 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)
函数可以通过代理适当地调用它们的托管对应物。但现在问题已经开始浮出水面。
- 纯本机进程能否加载启用 CLR 的 DLL?我见过有人谈论基本上从启用 CLR 的代码中创建一个静态库,然后将其与纯本机代码链接到“部分托管、部分本机”代理 DLL。但在那一点上,混乱开始出现,我不确定这个话题是否适用于我正在尝试做的事情。
- 如何将 DWORD 地址编组到 IntPtr (然后将其解组到 C# 端的函数指针)
- 我看到提到 AppDomains。这是我需要担心的事情吗?
- 我假设我的代理 DLL 需要在同一文件夹中运行托管扩展 DLL。我需要做一些特殊的事情来加载它,还是 CLR 和链接器会处理这个问题?
- 除了输出 DLL,我还得到了扩展名为“.exp”、“.ilk”和“.lib”的文件。我假设这些是用于静态链接的,当我使用 DLL 时我可以忽略它们吗?