Search code examples
c#.netx8664-bitanycpu

How to combine two managed x86/x64 dlls into one managed AnyCpu library?


A third party compiles unmanaged code (x86/x64 separated) and provides managed C# .NET dlls for either platform (x86/x64 separated):

  • FooManaged_x86.dll
  • FooManaged_x64.dll

This is what I receive (neither native code, nor unmanaged dlls).

I can then create a C#.NET application (or library) targetting either x86 or x64 and directly reference the corresponding managed dll - all fine, but restricted to one particular platform (not my goal).

My application can target AnyCpu (my goal), reference the x64 dll (bad, compiler warning), and it will work only when it actually runs as x64. Again, this is bound to one particular platform.

I know, that I can combine unmanaged x86/x64 dlls (with Fody.Costura) into one managed dll by dynamically loading the approriate dll at runtime (using DllImport and manual AssemblyLoad under the hood). I've done this with great success, but this method is not well suited for managed dlls. I would have to PInvoke from managed C# into managed C# dlls - which sounds wrong to me.

Q: Is there any way to combine two managed x86/x64 dlls into one managed AnyCpu dll without PInvoke?


Solution

  • Yes, there is. I've used LibZ successfully to package mixed-mode assemblies as resources into a managed AnyCPU assembly. The library picks the right assembly for the platform it runs on.

    It's the technique used in lz4net, by the same author.

    The command line in your case would be:

    libz inject-dll --assembly YourAnyCpuLib.dll --include FooManaged.x86.dll --include FooManaged.x64.dll

    The caveat is that the AnyCPU assembly still has to reference one of the platform-dependent libraries, so you'll get a warning at build time. Just pick the one that you're using for testing/development purposes.

    Also, make sure the third party license doesn't forbid you from embedding the assemblies into your own.