Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
718 views
in Technique[技术] by (71.8m points)

c# - Target 32 Bit or 64 Bit native DLL depending on environment

I have a native DLL which comes in both 32 bit and 64 bit versions (x86). I want to create a wrapper which works on both architectures (Any CPU) and loads the correct version of the DLL depending on the current environment (32 Bit or 64 Bit, at runtime!). This process should happen automatically, so that the users of my DLL do not need to target a specific architecture.

Are there any best practices on how to do that? Any examples that could guide 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 me to have 3 managed assemblies in addition to the 2 unmanaged libraries, which seems a bit overkill.

Is there any other solution?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Here is the solution I've used on many projects:

  • name the 32-bit assembly with a "32-bit oriented name". For example MyAssembly.Native.x86.dll
  • name the 64-bit assembly with a "64-bit oriented name". For example MyAssembly.Native.x64.dll
  • compile the managed assembly as 'Any Cpu'
  • ship everything in the same path

Here 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 'MyTest' function which is the one I'll always use (the others are here just for correct bitness binding). It has the same signature than the other P/Invoke ones:

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

    MyTest86(myArg);
}

The advantages are:

  • you can ship all binaries (DLLs, EXEs, ...) in the same path
  • you support 32-bit and 64-bit processes and OSes with the same file layout
  • you don't have to resort to Win32 apis for changing dll load path

The inconveniences are:

  • you'll have 3 method declarations for 1 'real' method
  • you'll loose some CPU cycles because of the bitness test
  • depending on your context, sometimes you can't change the native DLLs names, so you just can't do this

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...