4

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?

Patrick Stalph
  • 792
  • 1
  • 9
  • 19
  • As far as I know, referencing the x86 will allow your compiled target to run on both x86 and x64. I even think it will allow you to compile your project to AnyCpu and not just x86 - but I am not entirely sure. – gilmishal Dec 13 '16 at 09:39
  • @gilmishal: Not tested, but... For many things x86 is a good default, agreed. However, my 3rd party library works on large files / data sets, so 64bit provides actual benefit. – Patrick Stalph Dec 13 '16 at 10:31

1 Answers1

3

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.

Lucas Trzesniewski
  • 50,214
  • 11
  • 107
  • 158
  • 1
    It turned out that for my particular scenario the dependencies were to complex (including even static unmanaged libraries) and in a terrible state (I just found out that the x86 dll does not work at all). Neither Costura nor LibZ do support static unmanaged stuff (AssemblyResolve is never called). For simpler scenarios this will probably work. – Patrick Stalph Dec 21 '16 at 09:05