Question

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:

  • Is it possible to make working with VS on cross-platform apps less of a pain - to get it to add the appropriate references to the appropriate build targets without hand-holding?
  • Is there a simple way to make a .NET executable with platform-specific references that can run both in 32-bit and 64-bit mode, loading the appropriate assemblies as needed?
Was it helpful?

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

OTHER TIPS

My answer is YES. A possible approach is to use addin architecture so it works like this,

  1. When your C# application runs on x86, it loads the x86 version of the addin.
  2. When it runs on x64, it loads x64 version.

Then you prepare two projects for the addin versions. One is configured to compile for x86, while the other for x64. In turn, the x86 addin wraps over x86 build of the C++ library, and the x64 over x64 build of the C++ library.

This is slightly complicated because you have to maintain two addin project files, while the source files can be shared.

Using addin architecture, the addin libraries are loaded at runtime, so you have plenty of time to detect if now on x86 or x64, and then decide which addin to load.

Hope this help.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top