这是相当复杂的,所以请耐心等待。我有一个第三方程序(“目标”),用Native(仅限Win32)C ++编码。作为目标设计的一部分,它实现了一个dll-plugin系统。当置于程序的“ext”目录中时,本机DLL由目标加载。然后,目标会根据需要调用每个DLL提供的四种方法(Initialize,SendHook,RecvHook,Terminate)。正如您可能从函数名称中猜到的那样,加载项会挂钩目标中的某些函数。我没有目标的源代码。
其中一个加载项是旧的和错误的 - 更不用说令人困惑而且相当难看。它是用Delphi编写的(当然,编译为win32 DLL)。在过去的几周里,我一直在增强和翻译C#的加载项(我称之为“扩展”)。它现在已经完成了,所以我把注意力转移到了加载扩展的目标(它是作为类库构建的)。
显然,目标(本机C ++)无法直接加载扩展(托管C#)。因此,在研究之后,我似乎只需要一个“代理”DLL(用VC ++编写并支持CLR),它将加载我的扩展,然后处理从目标到扩展的方法调用。
“简单”。是的,对。我现在比一个Skittles包中的变色龙更加困惑。我已经看到了关于使用COM的东西,这在性能和进程内存权限方面都是我需要避免的,因为扩展将调用一些方法(通过句柄传递给代理)。另外,我已经看过有关tlb和#import指令的内容。这似乎也不是正确的方法。
我遇到了这篇文章https://sites.google.com/site/srinivasnzd/csincppviacpp-cli,它似乎终于走上正轨。实际上,我可以从C ++代理中调用我的托管C#就好了。作为奖励,它出现(我还没能用实际目标测试它)__declspec(dllexport)
函数可以通过代理适当地调用它们的管理对应物。但现在问题已经开始突然出现。
答案 0 :(得分:2)
在不使用C ++包装器的情况下,看看这个template是否有一些帮助导出C#代码。
不幸的是,开箱即用没有DllExport属性,因此您需要一个C ++包装器,或者您需要修改IL代码以执行导出。
编组地址没有问题,只需要注意C#端的函数指针,因为你总是需要确保有一个引用来使它们远离GC收集器。如果你保留一个静态引用是最简单的 - GC无法在非托管代码中看到对函数指针的引用,因此它可能会清理它。
如果你有几个c#模块,应用程序域很重要 - 如果它们共享相同的代码,它将成为一个问题
exp来自链接器,ilk和lib与链接器相关,因此我希望您不需要复制它们,但在调试时可能需要它们。