我有一个关于为32位DLL正确编写COM / ATL包装器的问题。
这是问题所在。正如我的其他一些问题所暗示的那样,我经常需要在大型代码库上执行编码工作,其中包括从不同供应商的恐惧链接的库。我们的软件可以在各种机器上运行,可以在各种架构上运行。这段代码主要用C#编写,C ++ DLL链接或编译/链接,然后在必要时从C#调用P /(在我看来,比托管C ++更容易实现)。
无论如何,一个这样的程序包含C#代码,它必须与几个64位DLL连接,源不可用。该软件的目标主机均为64位。没问题。因此,在AnyCPU模式下运行的C#会自动生成为64位(没有WoW),并且能够无缝地P / Invoke这些预编译的第三方64位DLL。
有一个这样的DLL,我只能使用32位版本。无法获得此DLL的64位版本。我有1.)32位DLL,一个包含函数导出的头文件(即#define EXP __declspec(dllexport),EXP BOOL WINAPI DLL_Function(IN int myInt,OUT int * result);和3.)相应的32位lib文件。
经过广泛的研究,我了解到,显然,COM / ATL是从64位进程访问32位DLL的正确方法。显然,我在WoW下生成了一个32位的COM进程,并与它进行交互。从架构的角度来看听起来不错,但我找不到任何有关如何专门执行此操作的教程或说明。我已经尝试过使用Visual Studio 2010的ATL向导,但我仍然不知道如何正确地执行此操作。有自动化工具吗?任何模板或教程?我保证我已尽最大努力搜索网络,并且只是想知道1.)如果我以正确的方式接近这个问题,或者2.)你知道任何资源吗?或者3。)任何人都有这种通用的IPC模板吗?
从我在SO上看到的,似乎这样的图像不匹配对于程序员来说是一个常见的问题,但是我还没有找到任何详细的解释(或至少指向详细的解释),除了“使用COM / ATL”。我以前的一篇帖子产生了一个响应,其中P / Invoke签名调用的问题已经非常详细地充实了,这太棒了 - 我想知道我们是否可以启动一个“确定的”64/32位跨架构讨论就在这里!
谢谢!
-Kadaj
编辑:我已经了解http://blog.mattmags.com/2007/06/30/accessing-32-bit-dlls-from-64-bit-code/,并了解架构,但我想知道实施细节。
答案 0 :(得分:1)
您可以在几分钟内获得简约的ATL解决方案。
分步说明:
IFoo
IFoo
接口添加方法,并在CFoo类中添加相应的实现,例如: CFoo::Bar
/regserver
参数运行一次)x64
,将COM引用添加到上面步骤5中构建的ATL COM服务器C#:
class Program
{
[STAThread]
static void Main(string[] args)
{
HostLib.Foo foo = new HostLib.Foo();
foo.Bar();
}
}
C ++ IDL:
[
// ...
]
interface IFoo : IDispatch
{
[id(1)] HRESULT Bar();
};
C ++:
// IFoo
STDMETHOD(Bar)()
{
MessageBox(GetActiveWindow(), _T("Hello, 32-bit World!"),
_T("Information"), MB_OK);
return S_OK;
}
64位C#代码启动32位COM EXE并调用Bar方法。
答案 1 :(得分:1)
最终,您需要在32位进程中托管32位dll,并将数据与64位进程进行编组。
首先,我应该解释一下COM和DCOM是什么:
在C / C ++ / VB6 / etc之上提供了一个约定,它通过定义的接口标准化调用和交换数据。它还有一个注册表,用于将对象的相关dll加载到您的进程中。
介绍编组和代理的概念,您可以在其中调用接口,但是它的一个代理将包装参数的命令推送到另一个进程的命令管道,等待结果并解压缩响应。该过程可以在不同的计算机上,甚至具有不同的处理器体系结构。
所以你可以使用DCOM来解决你的问题,但学习曲线很大,而且它对你想要的东西来说几乎太强大了。
您需要查看应用程序所需的体系结构以确定正确的解决方案,但我将介绍一些高级主体。
如果您创建一个32位.Net进程/服务来托管DLL,那么您可以研究一种在64位和32位进程之间执行IPC的技术之一。您需要决定是否要为每个64位进程分配一个或每个系统一个进程,以及它的生命周期应该是什么。 然后,您需要找到一种交换数据的方法,并整理调用。
WCF 可能是一个很好的(但很复杂的)赌注,如果你想要每台机器一个主机进程并且具有相对复杂的接口。
JSON RPC / HTTP 可能是另一个更轻量级的解决方案,您需要注意安全性。
STDIO 如果你可以逃脱它,编写一个32位命令行应用程序,只需通过STDIO管道数据,这很容易保护并具有一定的优雅unix。
这些解决方案的优点在于,您可以尽可能多地保留.Net土地,这将减少学习曲线。