Dave Thieben
Dave Thieben

Reputation: 5427

NuGet package for C++/CLI library for use in C# libraries

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.

Upvotes: 3

Views: 1387

Answers (1)

Kristof U.
Kristof U.

Reputation: 1281

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.

Upvotes: 2

Related Questions