Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Managed code references between any cpu and x64

I have a mixed-mode C++/CLI project which is compiled as x86 and x64 frozen dlls.

I have a C# app that needs to use this project which is compiled as "Any CPU". How can I properly reference the correct dll from the c# app? If I right click add reference I must select only 1 of the 2 dlls.
My "ANY CPU" C# app will sometimes run as x64 and sometimes as x86 process.

I've heard you can maybe do this via a smart config file.

like image 248
CSharpMan Avatar asked Mar 04 '11 15:03

CSharpMan


Video Answer


2 Answers

There are several ways to deal with this. First one is simplest, acknowledge the fact that your app actually does have a dependency on the target architecture. And that AnyCPU isn't the proper setting. It is very rare to need the humongous virtual address memory space you get from x64, especially since you also want and need to make it work on x86. So set the Platform target of the EXE to x86 and you're done.

Second is concluding that this is simply a deployment problem. All you have to do is copy the x64 build of the mixed-mode assembly when your app is installed on a 64-bit operating system, the x86 build on a 32-bit operating system. You'll need to create a Setup project that takes care of this. The simplest way is to create two of them. Also the only way afaik.

Third is the one with bells on where it works either way, the one you no doubt are asking about. This requires changes to code, project and installer. What you need to do is write a post-build event that create two subdirectories with names like "x86" and "x64". And copy the respective version of the DLL into them. This ensures that the CLR cannot find these assemblies.

In your code you must write an event handler for the AppDomain.CurrentDomain.AssemblyResolve event. Subscribe it in your Main() method, well before you try to use any types from the assembly. The event handler must use Assembly.LoadFrom() to load the correct assembly from the subdirectory, based on the value of IntPtr.Size. It is 8 when you run in 64-bit mode.

I should mention yet another approach but that's generally frowned-upon at SO. Install both assemblies into the GAC. Everything is automatic.

like image 79
Hans Passant Avatar answered Sep 23 '22 22:09

Hans Passant


Even if your C++ project compiles twice it should have the same managed interface for both x86 and x64 DLL's. Hence as long as your not using strong name signing it shouldn't matter which version of the DLL you reference. What's important is that the correct version is deployed on the target machine.

like image 44
JaredPar Avatar answered Sep 21 '22 22:09

JaredPar