1
votes

I have a managed C# project (targeting Any CPU) that references an unmanaged C++ DLL. I want to deploy my C# project as Any CPU, but my C++ DLL does not have an Any CPU option. My C++ DLL can only target the ARM, Win32, and x64 platforms. For convenience, I would like to build all of those to the same directory as my C# project and have my C# project reference them dynamically; I would like my output directory to contain the ARM, Win32, and x64 versions of my unmanaged DLL. As such, how could I make my solution build multiple platform targets for the same project?

1

1 Answers

1
votes

I found a workaround to what I want.

The first thing you need to do is use MSBuild on your project file in order to build the DLL under another platform. My solution has my project building as x64 so I need to build the x86 version as an additional post-build step, so what I did was I added a post-build script to my managed C# project in order to facilitate this process:

del "$(TargetDir)Unmanaged_x64.dll"
ren "$(TargetDir)Unmanaged.dll" Unmanaged_x64.dll
del "$(TargetDir)Unmanaged_x86.dll"
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" "$(SolutionDir)Unmanaged\Unmanaged.vcxproj" /p:Configuration=$(ConfigurationName) /p:Platform=x86
copy "$(SolutionDir)Unmanaged\$(ConfigurationName)\Unmanaged.dll" "$(TargetDir)Unmanaged_x86.dll"

Now, in my C# application, I have an assembly resolver in my App.xaml.cs file:

protected override void OnStartup(StartupEventArgs e)
{
    ...
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
    ...
}

Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    if (args.Name == "Unmanaged, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null")
    {
        if (Environment.Is64BitOperatingSystem)
        {
            return Assembly.LoadFrom(String.Format("{0}\\{1}", AppDomain.CurrentDomain.BaseDirectory, "Unmanaged_x64.dll"));
        }
        else
        {
            return Assembly.LoadFrom(String.Format("{0}\\{1}", AppDomain.CurrentDomain.BaseDirectory, "Unmanaged_x86.dll"));
        }
    }
    return null;
}

Works great for my needs; may need tweaks for yours! Cheers, everyone.