【发布时间】: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) 函数似乎(我还不能用实际目标测试它)可以通过代理适当地调用它们的托管对应物。但是现在问题已经开始出现了。
- 纯本机进程能否加载启用 CLR 的 DLL?我见过有人谈论基本上从启用 CLR 的代码中创建一个静态库,然后将其与纯本机代码链接到“部分托管、部分本机”代理 DLL。但那时,混乱开始出现,我不确定这个主题是否适用于我正在尝试做的事情。
- 如何将 DWORD 地址封送为 IntPtr(然后将其解封为 C# 端的函数指针)
- 我看到提到了 AppDomains。这是我需要担心的事情吗?
- 我假设我的代理 DLL 需要在同一文件夹中具有托管扩展 DLL 才能运行。我需要做一些特殊的事情来加载它吗,还是 CLR 和链接器会处理这个问题?
- 除了输出 DLL,我还得到了扩展名为“.exp”、“.ilk”和“.lib”的文件。我假设这些是用于静态链接的,我可以在使用 DLL 时忽略它们?
【问题讨论】:
-
我认为是那些在吃喝玩乐袋中寻找变色龙的人感到困惑。
-
可怜的变色龙不知道该变成什么颜色...
-
啊,我明白了。我想最后是我糊涂了。
-
这就是为什么我非常害怕 Win32 的古老语言。这也是为什么我们需要停止使用像 VB6 这样的语言和像 IE6 这样的程序。
-
如果有帮助,请查看filterdotnet.codeplex.com 并查看他如何设法将本机代码与托管代码链接起来。具体来说,查看源代码树中的
native/clr.cpp并查看CorBindToRuntimeEx以及加载CLR 的相关方法。 IIRC 托管模块必须在 GAC 中,至少在这种情况下是这样。研究此代码应该可以帮助您至少回答一些问题,G/L。顺便说一句,在变色龙 n 吃喝玩乐的笑话里大声笑 :)