.netc++visual-studiocross-platformplatform-specific

Referencing a platform-specific library from a non-specific .NET app


I often need to include little bits of native code in my C# apps, which I tend to do via C++/CLI. Usually I just need to use a C++ library for which there exists no good alternative for .NET; but sometimes performance is a factor too.

This is problematic; doing so means adding a reference to a specific x86 or x64 library. Most libraries support both 64-bit and 32-bit compilation, or require only minor modifications to work under 64-bit. However, I can only reference one of the versions from a particular C# project build target. That means I need to add several build targets by hand for every project in the solution.

VS.NET is extremely unhelpful in this case: If you add a C++ library and C# library to the same solution, and the C# and C++ libraries have both 32 and 64 bit targets, your solution will contain an "Any CPU" target, a "Mixed Platforms" target, a x64 target, a x86 target (which is what C# calls 32-bit), a win32 target (which is what C++ calls 32-bit), and maybe more; all in at least two versions (being Release and Debug, unless you've added more).

This get's messy fast, and for no good reason. The obvious behaviour shouldn't be that tricky: if I have a C# project referencing a C++ project, then it should be somewhat obvious that the 64-bit version should reference the 64-bit version, and similarly for 32-bits.

The worst part of it all is that all this results in two separate but identical executables: a Any CPU .NET project can work unmodified in both 32 and 64 bit modes, but I've not found a way to load the appropriate platform specific supporting libraries depending on the mode the app was started in.

To summarize this long ramble:


Solution

  • The main question you should ask yourself is, do you need a 64-bit version. For details see blogs posts by Scott Hanselman and myself.

    If you really need both versions, you can also load both the 32bit and 64bit library into the GAC, so the runtime can chose the correct one automatically.

    If you don't want to GAC your libraries, you can also take a look at this StackOverflow post, where a way to load the correct assembly is described. I don't really like this solution though, because it really requires a plugin model