I have a native C++ library with a .NET wrapper, all built in Visual Studio 2003 and 2005. We recently ported the .NET wrapper library to VS2005 and it doesn't work. The .NET wrapper library is mixed-mode, with native C++ and Managed extensions classes, and a bit of native assembly in places. Assume a release binary in all cases.
The VS2003 .NET dll works perfectly without any complaints, but I am so far unable to get anywhere with VS2005. I have other native applications built on the native library so the problem appears to be constrained to the linker settings and dynamic linking rules surrounding the .NET library specifically.
The .net library is using managed extensions for C++ (/clr:oldSyntax) so some options are limited in the properties sheet.
The original problem I had was runtime error R6034: An application has made an attempt to load the C runtime library incorrectly
. This was fixed by including an embedded manifest in the assembly. The Exception trace for this follows:
Unhandled Exception: System.IO.FileLoadException: A dynamic link library (DLL) initialization routine failed. (Exception from HRESULT: 0x8007045A)
at Corp.Blah.BlahConsole.Program.Main(String[] args)
After embedding a manifest in the assembly, I get a new error. The side-by-side error in the question title comes from Dependency Walker. Full text:
Error: The Side-by-Side configuration information for "s:\release\MDM3NET80.DLL" contains errors. This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem (14001).
Warning: At least one delay-load dependency module was not found.
Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.
As far as I can tell the delay load warnings pertain to parts of Kernel32.dll have changed in different versions of Windows, but are not relevent to my application, notably MPR.DLL, IESHIMS.DLL and WER.DLL. These warnings seem to be unimportant.
Attempting to load the .NET dll with a small console application produces a System.IO.FileLoadException
:
Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'BLAH, Version=5.0.0.22, Culture=neutral, PublicKeyToken=ffbc9a05441709bc' or one of its dependencies. This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem. (Exception from HRESULT: 0x800736B1)
File name: 'BLAH, Version=5.0.0.22, Culture=neutral, PublicKeyToken=ffbc9a05441709bc' ---> System.Runtime.InteropServices.COMException (0x800736B1): This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem. (Exception from HRESULT: 0x800736B1)
at Corp.Blah.BlahConsole.Program.Main(String[] args)
This error occurs on the development machine as well as others so I do not expect Visual Studio to be trying to use the wrong version of the MSCRT dlls.
I extracted the following assembly from the built DLL:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity name="Corp.Blah.BlahNet">
</assemblyIdentity>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.762" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b">
</assemblyIdentity>
</dependentAssembly>
</dependency>
</assembly>
The indicated CRT dlls can be found in the WINSxS directory under x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_6b128700
, along with a bunch of other versions. As far as I can tell this means the correct versions of the libraries should be linked at runtime as suggested by this link.
I have tried various ways of fiddling with the linker and manifest settings, including the following:
- Build with and without an embedded manifest. Adding a manifest fixes the R6034 error but surfaces the FileLoadException/side-by-side issue.
- Put MSCRT dlls in the output folder and attempt to link to them instead of statically linking the .lib files.
- Changing the code generation runtime library from /MD to /MT (not supported on /clr:oldSyntax projects and I still need to support VS2003 so upgrade not possible).
- Properties -> Linker -> Generate Manifest: Yes (Default), No - (same result)
- Tried porting the .NET wrapper to VS2010 and link against the VS2005 native binaries - Same issues and error messages apply.
I have been through many similar questions and forum posts and none of the solutions offered work so far. Can anyone help? I'm getting a bit lost with this one.
Additional information from Event Viewer
In the System Event Viewer, the errors are reported by source: SideBySide, full text:
Generate Activation Context failed for S:\release\BlahNet.dll. Reference error message: The operation completed successfully.
Looks like a candidate for the Daily WTF.
Update: Tried starting from scratch with no luck
I have made another attempt by building the VS2005 project file from scratch and importing the sources. I thought I might be onto something when the key signing system broke down as documented here. After trying the suggested key-signing method, I still get the same FileLoadException
when trying to use the DLL.
The cause of these errors turned out to be rather unintuitive.
The native library wrapped by the .Net DLL is composed of various modules, each with their own DLL, and each wrapping a third-party library or providing plug-in-like functionality. Some of these native DLLs were linked without a manifest.
While there is no direct link between the .Net wrapper and the plug-ins, it seems the missing manifests cause the runtime error (R6034). Native applications linking against these libraries have not had similar runtime errors so the behaviour of the program loader must be different for .Net assemblies when loading native DLLs.
Telling the linker to include the manifests for all native libraries seems to fix the problem and does not damage the native applications.