What is the best way to support multiple architectures in a mixed managed / unmanaged environment?

Background

We have a .NET library referencing one of our unmanaged DLLs, say:

  • Dotnet.dll
  • Unmanaged.dll

So far, Unmanaged.dll has only been 32-bit, so DotNet.dll is marked with a 32-bit CPU type.

Need to add 64-bit support. How to organize a DLL? DotNet.dll IL code will be the same for 32-bit and 64-bit versions.

Option 1

  • 32-bit library folder
    • DotNet.dll, processor type 32-bit
    • Unmanaged.dll compiled as 32-bit
  • 64-bit library folder
    • DotNet.dll 64-bit processor type
    • Unamanged.dll compiled as 64-bit

In this case, the developer using these libraries is forced to make 2 applications: 32-bit and 64-bit. But in this case I know exactly what is happening.

Option 2

This is the same as Option 1, except that DotNet.dll is of the AnyCPU processor type.

  • 32-bit library folder
    • DotNet.dll, processor type AnyCPU
    • Unmanaged.dll compiled as 32-bit
  • 64-bit library folder
    • DotNet.dll, processor type AnyCPU
    • Unamanged.dll compiled as 64-bit

I don’t like this, because the developer using these libraries when redistributing his application cannot do a good job to make his application not crash without setting the processor type in his application:

  • If they use the 32Bit Libraries Folder, in a 64-bit OS their process will crash
  • If they use the 64Bit Libraries Folder, on a 32-bit OS their process will crash

This makes Option 1 above Option 2.

Option 3

  • Unmanaged_x32.dll compiled as 32-bit
  • Unmanaged_x64.dll compiled as 64-bit
  • DotNet.dll, processor type AnyCPU

DotNet.dll at runtime will determine which bit it launches, and then PInvoke the correct Unmanaged.dll.

Question (s)

  • As a developer of these libraries, which option makes sense?
  • As a developer using the DotNet.dll library, which option makes the most sense?
    • For option 3, if you are using DotNet.dll, would you like to know that the runtime library determines what Unmanaged.dll to use?
    • How about redistributing your application with these libraries?
  • Are there any missing options?
+7
32bit-64bit managed unmanaged
source share
3 answers

I would choose option 3, compile a managed assembly for AnyCPU, and name unmanaged assemblies for my architecture. I see two separate problems that affect this solution:

Should I compile a managed assembly for AnyCPU or a specific architecture?

I think that .NET developers would not expect a separate file link for each architecture. I would use AnyCPU to have exactly one DLL.

Should dll libraries explicitly specify their architecture?

If you are using AnyCPU for a managed build, there is exactly one dll, so that's a moot point.

For an unmanaged build, there may be an expectation that files compiled for different architectures are named differently. Technically speaking, naming files differently allows you to put files for both architectures in the same directory; this means that you go to another file at runtime depending on the architecture, but this is not a huge burden. I would name the files differently.

+4
source share

Option 3 seems the easiest, while option 1 seems the safest. From the point of view of which library to call, it seems that it would be difficult to manage them if you are not dealing with a huge number of calls. The main problem is that you will have to declare any given function twice, using different names for the 32-bit and 64-bit versions, and then simply change the DllImport attribute to indicate the desired target. Your stub function will have to decide at runtime which you need to call.

Please note: logistics aside, there is no need to include both in your library folder. As long as you do not call the β€œwrong” library, excluding it will have no effect.

+2
source share

What am I doing:

I am sending DotNet.dll compiled for AnyCPU with portable P / Invoke directives (for example, API declarations should be).

I send unmanaged_32.bin and unmanaged_64.bin and install only the correct one for the architecture as unmanaged.dll during installation.

The trick that still works is to install unmanaged.dll as follows:

x86: C: \ Program Files (x86) \ Common Files \ unmanaged.dll x64: C: \ Program Files \ Common Files \ unmanaged.dll

If C: \ Program Files \ Common Files is in the system path, this will cause P / Invoke to automatically grab the required DLL.

+2
source share

All Articles