3

What is the right way to construct a NuGet package for a mixed-mode C++/CLI library?

I have 32-bit and 64-bit builds of the dll, and an ASP.NET Core app (targeting full .NET framework only) using it that will be built for both platforms. The app's solution platform is "AnyCPU".

I have tried using the /runtimes/ folders, but then Visual Studio can't find the managed code to compile against.

Currently I have 2 packages, like "MyLibrary" and "MyLibrary64", with the dll in the /lib/ folder and conditional PackageReference in my csproj, but this doesn't feel right. Additionally, when I compile in VS, I get:

warning MSB3270: There was a mismatch between the processor architecture of the project
being built "MSIL" and the processor architecture of the reference "MyLibrary.dll", "x86".
This mismatch may cause runtime failures. Please consider changing the targeted processor
architecture of your project through the Configuration Manager so as to align the
processor architectures between your project and references, or take a dependency on
references with a processor architecture that matches the targeted processor architecture
of your project.

This questions is similar, but has no answers: Create NuGet package for C++/CLI (mixed) assembly

Update/Clarification:

the app can run either hosted in IIS (64-bit) or as a standalone self-hosted installed application (32-bit), so both are unfortunately necessary.

Dave Thieben
  • 5,388
  • 2
  • 28
  • 38
  • Nuget never had dedicated support for C++/CLI assemblies, so it is not going to help you solve this warning. Which is a real one, your project is unlikely to run. An asp.net app is pretty likely to run in 64-bit mode and can't use the x86 build of that assembly. AnyCPU is fairly wishful thinking in this scenario, the bitness of the project must match the flavor of the native code. Do consider whether there is any point in building the x86 flavor at all. – Hans Passant Mar 23 '18 at 14:46
  • updated the question – Dave Thieben Mar 23 '18 at 16:16
  • That is not a clarification, it merely adds more unspecified wishful thinking. That odds that nuget is going to be helpful ought to be quite low, just help the OS find the correct DLL: https://stackoverflow.com/a/2594135/17034 – Hans Passant Mar 23 '18 at 16:27
  • I forgot the biggest problem, .NETCore has no support for C++/CLI. – Hans Passant Mar 23 '18 at 16:31

1 Answers1

2

As Hans already pointed out, the platform of the C++/CLI project must match the mode in which the managed code runs. Hence, an assembly set to AnyCPU that references a (mixed-mode) assembly set to x86 may always fail to load if it is loaded in a 64 bit process.

There are three ways I know of to fix this issue:

First, live with the warning and make sure that the process in which the assemblies are loaded is always a 32-bit process. I wouldn't recommend this.

Second, switch your application to x86 which guarantees that it always runs in a 32-bit process. This is the easiest and cleanest way, but it pins you to 32 bit.

Third, make a NuGet package that contains both, 32- and 64-bit builds of your mixed assembly together with an automatic loader switch. To this end, you need to make sure that the mixed assembly is not found (i.e. by renaming it in the NuGet package) and that there is a AnyCPU assembly that registers AppDomain.AssemblyResolve with an event handler that loads the 32- or 64-bit version of your mixed assembly, depending on the current process.

The third approach allows to provide a NuGet package with mixed-mode assemblies that can be referenced from AnyCPU assemblies. Note, however, that AppDomain.AssemblyResolve is a global concept and may interfere with other components in your application, which may lead to non-trivial bugs.

Kristof U.
  • 1,263
  • 10
  • 17