这有点复杂,请耐心阅读。我有一个第三方程序(“目标”),它是用本地(仅限Win32)C++编写的。作为目标设计的一部分,它实现了一个dll插件系统。当本地DLL放置在程序的“ext”目录中时,目标会加载它们。然后,目标会相应地调用每个DLL提供的四个方法(Initialize、SendHook、RecvHook、Terminate)。正如您可能从函数名称中猜到的那样,这些插件在目标中挂钩某些函数。我没有目标的源代码。
其中一个插件很旧、有缺陷,而且令人困惑且相当丑陋。它是用Delphi编写的(当然编译为win32 DLL)。过去几周,我一直在增强并将该插件翻译成C#(我称之为“扩展”)。现在它已经完成,所以我把注意力转向让目标加载该扩展(它构建为类库)。
显然,目标(作为本地C++)无法直接加载扩展(托管C#)。因此,在调查后,似乎我只需要一个“代理”DLL(使用CLR支持编写的VC++)来加载我的扩展,然后负责将方法调用从目标传递到扩展。
"简单。"是吗?现在我比一只袋子里的变色龙更加困惑了。我看到一些关于使用COM的东西,这显然是我需要避免的,无论是从性能还是进程内存权限方面,因为扩展将调用一些方法(通过句柄传递给代理)。此外,我也看到了一些关于tlb和#import指令的东西。这似乎也不是正确的方法。
我发现了这篇文章https://sites.google.com/site/srinivasnzd/csincppviacpp-cli,它似乎终于走上了正确的轨道。事实上,我可以很好地从C++代理中调用我的托管C#。作为一个额外的奖励,它似乎(我还没有能够与实际目标进行测试)可以适当地调用它们的托管对应函数,虽然是通过代理。但现在问题开始出现了。"
其中一个插件很旧、有缺陷,而且令人困惑且相当丑陋。它是用Delphi编写的(当然编译为win32 DLL)。过去几周,我一直在增强并将该插件翻译成C#(我称之为“扩展”)。现在它已经完成,所以我把注意力转向让目标加载该扩展(它构建为类库)。
显然,目标(作为本地C++)无法直接加载扩展(托管C#)。因此,在调查后,似乎我只需要一个“代理”DLL(使用CLR支持编写的VC++)来加载我的扩展,然后负责将方法调用从目标传递到扩展。
"简单。"是吗?现在我比一只袋子里的变色龙更加困惑了。我看到一些关于使用COM的东西,这显然是我需要避免的,无论是从性能还是进程内存权限方面,因为扩展将调用一些方法(通过句柄传递给代理)。此外,我也看到了一些关于tlb和#import指令的东西。这似乎也不是正确的方法。
我发现了这篇文章https://sites.google.com/site/srinivasnzd/csincppviacpp-cli,它似乎终于走上了正确的轨道。事实上,我可以很好地从C++代理中调用我的托管C#。作为一个额外的奖励,它似乎(我还没有能够与实际目标进行测试)可以适当地调用它们的托管对应函数,虽然是通过代理。但现在问题开始出现了。"
- 一个纯本地进程能否加载启用了CLR的DLL?我看到有人讨论基本上将启用CLR的代码制作成静态库,然后将其与纯本地代码链接以形成“部分托管、部分本地”代理DLL。但是在那一点上,困惑开始出现,我不确定该主题是否适用于我正在尝试做的事情。
- 我该如何将DWORD地址转换为IntPtr(然后在C#端解除marshaling以获得函数指针)?
- 我看到提到了AppDomains。这是我需要担心的事情吗?
- 我假设我的代理DLL需要在同一文件夹中具有托管扩展DLL才能运行。我需要做些特殊的事情来加载它,还是CLR和链接器会处理它?
- 除了输出DLL之外,我还得到了扩展名为“.exp”、“ilk”和“.lib”的文件。我假设这些是用于静态链接的,当我使用DLL时可以忽略它们?