Managed code references between any cpu and x64
Asked Answered
I

2

5

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.

Impossible answered 4/3, 2011 at 15:53 Comment(1)
I believe you can do this by editing the manifest file. I remember a UI for doing this: msdn.microsoft.com/en-us/library/xhctdw55.aspx but I don't remember what exactly you need to do.Extrovert
H
2

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.

Harpist answered 4/3, 2011 at 16:7 Comment(3)
If I reference say the x64 one and set the project settings to do not copy to output folder, will a x86 developer on my team from an x86 machine have any trouble building? Other than he will have to manually copy the correct dll to his output folder exactly once. I think it is a non issue right?Impossible
@CSharpMan, building shouldn't be an issue as it's possible for an x86 machine to build the x64 DLL's (if the proper tools are installed). Running would definitely be an issue though.Harpist
@CSharpMan, the way I would approach this problem is have my Debug settings on the application constrain the managed app to x86 but leave the retail config to AnyCPU. This way everyone can build and run it under debug.Harpist
I
5

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.

Ishii answered 4/3, 2011 at 16:32 Comment(2)
why is it frowned upon to install both into the GAC?Impossible
You are asking the wrong person, I religiously avoid cargo cult programming and practices. Start a new question about it.Ishii
H
2

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.

Harpist answered 4/3, 2011 at 16:7 Comment(3)
If I reference say the x64 one and set the project settings to do not copy to output folder, will a x86 developer on my team from an x86 machine have any trouble building? Other than he will have to manually copy the correct dll to his output folder exactly once. I think it is a non issue right?Impossible
@CSharpMan, building shouldn't be an issue as it's possible for an x86 machine to build the x64 DLL's (if the proper tools are installed). Running would definitely be an issue though.Harpist
@CSharpMan, the way I would approach this problem is have my Debug settings on the application constrain the managed app to x86 but leave the retail config to AnyCPU. This way everyone can build and run it under debug.Harpist

© 2022 - 2024 — McMap. All rights reserved.