Target 32-bit or 64-bit native DLL memory, depending on the environment

I have a native DLL that comes in both 32-bit and 64-bit versions (x86). I want to create a shell that works on both architectures (any processor) and loads the correct version of the DLL depending on the current environment (32 bits or 64 bits at run time!). This process should happen automatically, so users of my DLL do not need to target a specific architecture.

Are there any recommendations on how to do this? Any examples that could help me?

I found one possible solution that uses managed proxies for each architecture, and then uses the Assembly.Resolve event to load the correct version. However, this requires that I have 3 managed assemblies in addition to two unmanaged libraries that seem a bit crowded.

Is there any other solution?

+2
c # dll pinvoke
Apr 22 '14 at 9:25
source share
3 answers

Here is the solution I used in many projects:

  • name the 32-bit assembly with the β€œ32-bit oriented name”. For example, MyAssembly.Native.x86.dll
  • name the 64-bit assembly with the "64-bit oriented name". For example, MyAssembly.Native.x64.dll
  • compile the managed assembly as "Any Cpu"
  • send everything in one way

This is how I declare P / Invoke methods:

 [DllImport("MyAssembly.Native.x86.dll", EntryPoint = "MyTest")] private static extern void MyTest86(MyType myArg); [DllImport("MyAssembly.Native.x64.dll", EntryPoint = "MyTest")] private static extern void MyTest64(MyType myArg); 

And here is the corresponding function "MyTest", which I will always use (others are here only for the correct binding of the bit). It has the same signature as other P / Invoke:

 public static void MyTest(MyType myArg) { if (IntPtr.Size == 8) { MyTest64(myArg); return; } MyTest86(myArg); } 

Benefits:

  • you can send all binaries (dll, exe, ...) to the same path
  • you support 32-bit and 64-bit processes and operating systems with the same file location
  • You do not need to resort to Win32 apis to change the dll boot path.

Disadvantages:

  • you will have 3 method declarations for 1 'real' method
  • you will lose some processor cycles due to a bit test
  • depending on your context, sometimes you cannot change the names of the native DLLs, so you simply cannot do this.
+4
Apr 22 '14 at 10:24
source share

The way I do this is to p / call the LoadLibrary call before calling any of p / invokes to the library.

  • Use the execution assembly bit to determine which version of the unmanaged DLL to load.
  • Then call LoadLibrary to load it, passing the full path to the DLL.
  • Then, when you call p / invokes, the correct DLL is already loaded into the process, and p / invokes binds to it.

It depends on an unmanaged DLL with the same name for 32 and 64 bits. If it is not, then you have a problem. In this case, you may need to explicitly link the DLL with p / invoking GetProcAddress . This is not at all funny. Or do you realize the kind of forests that Simon describes in his answer.

+2
Apr 22 '14 at 9:28
source share

Take a look at Microsoft.WinAny.Helper and It'a DynamicNativeLibrary , which can help you with what you need.

0
Apr 22 '14 at 10:18
source share



All Articles