简体   繁体   中英

Ways to access a 32bit DLL from a 64bit exe

I have a project that must be compiled and run in 64 bit mode. Unfortunately, I am required to call upon a DLL that is only available in 32 bit mode, so there's no way I can house everything in a 1 Visual Studio project. I am working to find the best way to wrap the 32 bit DLL in its own exe/service and issue remote (although on the same machine) calls to that exe/service from my 64 bit app. My OS is Win7 Pro 64 bit.

The required calls to this 32 bit process are several dozen per second, but low data volume. This is a realtime image analysis application so response time is critical despite low volume. Lots of sending/receiving single primitives.

Ideally, I would host a WCF service to house this DLL, but in a 64 bit OS one cannot force the service to run as x86! Source . That is really unfortunate since I timed function calls to the WCF service to be only 4ms on my machine.

I have experimented with named pipes is .net. I found them to be 40-50 times slower than WCF (unusable for me).

Any other options or suggestions for the best way to approach my puzzle?

As you correctly note, there is no way to mix bitness in the same process. You need a separate process for your 32-bit part.

I think hosting a WCF Service is the right way to go. Your link only talks about wcfsvchost. I am pretty sure you can create your own Windows Service, and host the WCF service in that on 32 bit.

See this link: How to host a WCF service in a managed application . You can host your service in any managed application, including a Windows Service, and run it under the bitness you like.

This is the amount of code required to self-host a WCF service in your application, assuming you have just created a new service called MyService, and the appropiate configuration has been added to app.config:

class Program
{
    static void Main(string[] args)
    {
        using(ServiceHost host = new ServiceHost(typeof(MyService), new Uri[0]))
        {
            host.Open();
            Console.ReadKey();    
        }
    }
}

The above program will run just as well, also if you compile it explicitly as 32 or 64 bit.

None. Point. 32 bit dll in 64 bit process = no go.

What I do is run a 32 bit wrapper process and communicate with it using WCF - much like you do. I can force the OS to run 32 bit.

I have a core library (Tradex.Connectivity.Core), with the platform independant .NET code. I have two wrappers (Wrapper32.exe, Wapper64.exe) that start and load the independent code and then load the class (managed C++). Works like a charm.

THat pretty much is the only way for me - you can not crss load 32 and 64 bit elements.

I know this answer might be a little bit late, but some time ago I faced the exact same problem (loading a 32bit dll into an AnyCPU assembly on a 64bit machine).

As a solution, I wrote the LegacyWrapper . It basically consists of a 32bit wrapper exe loading the desired dll, communicating with your application via Named Pipes.

A call would look like this:

// 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 });
}

For some details, you can refer to this blog post .

Edit: Since Version 2.1, LegacyWrapper also supports loading 64bit DLLs from a 32bit process.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM