2

Is there a way to take an existing .NET assembly, compiled to either x86 or x64, and create another assembly with the same API but compiled as AnyCPU? The new assembly will never actually be executed; it will only be used as a compile-time reference.

Background

I have a .NET assembly that was written in C++/CLI. I'm putting it into a nuget package, using nuget's runtimes and ref folders to handle the 32 vs 64 bit issue. Normally the assemblies in the ref folder are compiled as AnyCPU, but that isn't an option for C++ assemblies. For now I've got a copy of the 32 bit version in the ref folder, but that causes a warning when included in an x64 project:

There was a mismatch between the processor architecture of the project being built "AMD64" and the processor architecture of the reference "c:...\myassembly.dll" "x86".

I realize this won't cause any problems at runtime, but I'd like to get rid of the warning if possible. If this were written in C# or VB I'd be able to use CorFlags to turn it into an AnyCPU assembly, but that trick doesn't work with C++ assemblies. When I set the ILONLY flag on a 32 bit C++ assembly, Visual Studio is no longer able to load the assembly at all.

So can anyone suggest how to create a version of this assembly that would be suitable for use as a compile time reference in a nuget package?

Darryl
  • 5,907
  • 1
  • 25
  • 36
  • I was thinking about this pure attribute, ILONLY should do it, but then you have to avoid tagging in any way the platform. Didn't https://stackoverflow.com/a/28291475/9293869 answer your question. At least the second answer with the assembly loading code based on the platform on runtime could help. Basically you provide then the loading dll for nuget in the lib folder but that will load the right one with the provided code. – JackGrinningCat Nov 20 '18 at 12:49
  • If you only need it for the metadata then the platform target doesn't matter. Metadata is architecture-agnostic. You however always get code even if you don't write any, C++/CLI requires a module initializer. And that can generate a linker warning in the project in which you use the assembly, presumably what you are really worried about. If you're sure that the assembly doesn't get loaded at all at runtime then you can use Corflags.exe to override the CLR header. – Hans Passant Nov 22 '18 at 11:53
  • Thanks @HansPassant. Yes, it's the warning I'm trying to get rid of. I know it doesn't cause any problems, but I'd prefer that consumers of my nuget package don't see a warning and assume something isn't working correctly. As far as using Corflags, unfortunately that approach didn't work. Before making any changes, a 32-bit C++ assembly has CorFlags = 0x10, while an Any CPU non-C++ assembly's CorFlags are 0x01. I can add the 0x01 bit, which is the ILONLY flag, but when I do Visual Studio can no longer use the assembly as a reference. And there's no way to clear the 0x10 bit w/ CorFlags. – Darryl Nov 28 '18 at 18:03
  • You don't give me enough cues to really help you. The /clr:pure option is still available even though they've been promising for a while to kill it. – Hans Passant Nov 28 '18 at 18:14
  • I ended up using DotPeek to create a C# assembly with the same API as the real assembly. I won't go down that road again, as it was very manual and time consuming to turn that tool's output into something I could compile. But it did the job. – Darryl Nov 28 '18 at 20:29
  • It's been quite a while, but in VS 2019 Update 8 I was able to use the x86 version of a c++/cli dll as `ref`for x64 compilation also by adding the ReferenceAssembly attribute to the assembly. It is then of course useless as Runtime dll but the architecture mismatch build warning goes away. https://stackoverflow.com/a/7555320/4920666 – smkanadl Jan 15 '21 at 17:11
  • @smkanadl, Nice! It may have been a while, but this is good information. I appreciate the comment. – Darryl Jan 21 '21 at 00:39

0 Answers0