代码之家  ›  专栏  ›  技术社区  ›  bufferz

从64位exe访问32位dll的方法

  •  13
  • bufferz  · 技术社区  · 14 年前

    我有一个项目必须在64位模式下编译和运行。不幸的是,我需要调用一个仅在32位模式下可用的dll,所以我无法在1 Visual Studio项目中容纳所有内容。我正在努力寻找将32位dll包装在自己的exe/service中的最佳方法,并从我的64位应用程序对该exe/service发出远程调用(尽管在同一台计算机上)。我的操作系统是64位Win7 Pro。

    对这个32位进程的所需调用是每秒几十次,但数据量很小。这是一个实时图像分析应用程序,因此响应时间至关重要,尽管体积很小。大量发送/接收单个原语。

    理想情况下,我会托管一个wcf服务来存放这个dll,但在64位操作系统中,不能强制该服务以x86方式运行! Source . 这真的很不幸,因为我将对WCF服务的函数调用在我的机器上的时间仅为4ms。

    我已经尝试过命名管道是.NET。我发现它们比WCF慢40-50倍(对我来说不可用)。

    有没有其他的选择或建议来解决我的难题?

    3 回复  |  直到 7 年前
        1
  •  9
  •   driis    14 年前

    正如您正确地注意到的,在同一个过程中没有混合比特率的方法。您的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位,那么它也可以运行。

        2
  •  4
  •   Assaf Lavie    14 年前

    一个也没有。点。64位进程中的32位dll=no go。

    我所要做的是运行一个32位包装器进程,并使用wcf与之通信——就像您所做的那样。我可以强制操作系统运行32位。

    我有一个核心库(tradex.connectivity.core),带有平台独立的.NET代码。我有两个包装器(WrPrPi32.exe,WaPrPix.exe),它们启动并加载独立代码,然后加载类(托管C++)。很有魅力。

    对于我来说,这几乎是唯一的方法——不能用CRSS加载32和64位元素。

        3
  •  1
  •   Franz Wimmer    7 年前

    我知道这个答案可能有点晚了,但不久前我遇到了完全相同的问题(在64位计算机上将32位DLL加载到任意CPU程序集中)。

    作为解决方案,我写了 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.