我有一个必须编译并以64位模式运行的项目。不幸的是,我需要调用一个仅在32位模式下可用的DLL,因此我无法在一个Visual Studio项目中容纳所有内容。我正在努力找到将32位DLL包装在自己的exe / service中的最佳方法,并从我的64位应用程序发出远程(尽管在同一台机器上)调用该exe / service。我的操作系统是Win7 Pro 64位。
这个32位进程所需的调用是每秒几十次,但数据量很小。这是一个实时图像分析应用程序,因此尽管音量低,响应时间仍然很重要。大量发送/接收单个原语。
理想情况下,我会托管一个WCF服务来容纳这个DLL,但是在64位操作系统中,不能强制服务作为x86运行! Source。这真的很不幸,因为我在我的机器上将对WCF服务的函数调用时间仅为4毫秒。
我已尝试使用命名管道.net。我发现它们比WCF慢40-50倍(对我来说无法使用)。
任何其他选择或建议,以最好的方式来解决我的难题?
答案 0 :(得分:9)
正如您所正确指出的那样,无法在同一过程中混合位数。您需要为32位部分单独处理。
我认为托管WCF服务是正确的方法。您的链接仅涉及wcfsvchost。我很确定你可以创建自己的Windows服务,并在32位上托管WCF服务。
请参阅此链接:How to host a WCF service in a managed application。您可以在任何托管应用程序(包括Windows服务)中托管您的服务,并在您喜欢的位置下运行它。
这是在您的应用程序中自托管WCF服务所需的代码量,假设您刚刚创建了一个名为MyService的新服务,并且已将相应的配置添加到app.config中:
class Program
{
static void Main(string[] args)
{
using(ServiceHost host = new ServiceHost(typeof(MyService), new Uri[0]))
{
host.Open();
Console.ReadKey();
}
}
}
上面的程序也会运行,如果你明确地将其编译为32或64位。
答案 1 :(得分:4)
无。点。 64位进程中的32位dll =不行。
我所做的是运行32位包装器进程并使用WCF与它进行通信 - 就像你一样。我可以强制操作系统运行32位。
我有一个核心库(Tradex.Connectivity.Core),平台独立的.NET代码。我有两个包装器(Wrapper32.exe,Wapper64.exe)启动并加载独立代码,然后加载类(托管C ++)。像魅力一样。
对我来说,这几乎是唯一的方法 - 你不能加载32位和64位元素。
答案 2 :(得分:1)
我知道这个答案可能有点晚了,但前段时间我遇到了同样的问题(在64位机器上将32位dll加载到AnyCPU程序集中)。
作为解决方案,我写了LegacyWrapper。它基本上由一个32位的包装器exe加载所需的dll,通过命名管道与您的应用程序通信。
电话会是这样的:
// Define delegate matching api function
private delegate int GetSystemMetrics(int index);
// Create new WrapperClient
// Remember to ensure a call to the Dispose()-Method!
using (var client = new WrapperClient())
{
// Make calls providing library name, function name, and parameters
int x = (int)client.Invoke<GetSystemMetrics>("User32.dll", "GetSystemMetrics", new object[] { 0 });
int y = (int)client.Invoke<GetSystemMetrics>("User32.dll", "GetSystemMetrics", new object[] { 1 });
}
有关详细信息,请参阅此blog post。
修改: Since Version 2.1, LegacyWrapper also supports loading 64bit DLLs from a 32bit process.