LoadLibrary 193

Max Ehrlich picture Max Ehrlich · Feb 19, 2012 · Viewed 7.1k times · Source

I am creating a C++/CLI dll that will be loaded into a legacy c++ application. The legacy application does this with a traditional call to LoadLibrary. Both the application and the C++/CLI dll are compiled in 64 bit mode.

When the LoadLibrary call happens, it fails with error 193. This usually means that some non-64bit component is trying to load. When I look at the dll load output in visual studio 2010, I see the the failure is occurring when mscoree.dll is being loaded (to be exact, I see my dll loaded, then mscoree loaded, then mscoree unloaded, then my dll unloaded, then the error returned). Specifically C:\Windows\System32\mscoree.dll is being loaded, when I examine this mscoree.dll, I find that it is targeting I386.

How can I ensure that my application will link against the correct mscoree.dll? I understand this could be done with a manifest, but I can't find any good information about setting one up. The ideal solution would allow compilation in 32bit or 64bit mode and target the correct mscoree.dll.

As a side note, I found an mscoree.dll in a side-by-side folder that I verified is 64bit mode and copied it into my application directory with the hopes that it would pick up that one first. This didnt work and the C:\Windows\System32 version was still loaded.

Thanks,

Max

Output of CorFlags.exe on the C++/CLI dll

Microsoft (R) .NET Framework CorFlags Conversion Tool.  Version  4.0.30319.1
Copyright (c) Microsoft Corporation.  All rights reserved.

Version   : v4.0.30319
CLR Header: 2.5
PE        : PE32+
CorFlags  : 16
ILONLY    : 0
32BIT     : 0
Signed    : 0

Output of pedump.exe on C:\System32\mscoree.dll

PS C:\Windows\System32> pedump.exe .\mscoree.dll
Dump of file .\MSCOREE.DLL

File Header
  Machine:                      014C (I386)
  Number of Sections:           0004
  TimeDateStamp:                4B90752B -> Thu Mar 04 22:06:19 2010
  PointerToSymbolTable:         00000000
  NumberOfSymbols:              00000000
  SizeOfOptionalHeader:         00E0
  Characteristics:              2102
    EXECUTABLE_IMAGE
    32BIT_MACHINE
    DLL
...

(pedump goes on from here to describe imports and exports but thats not important here)

Extended loading information

This is the full output from failed load.

Note: The C++/CLI dll is called DsfClr.dll
the output was obtained by running gflags.exe -i [exename] +sls and examining the results in a debugger

http://pastebin.com/FyumUiMN

UPDATE:

Using a tip posted in a below comment by Reuben, I was able to determine that mscoree.dll is indeed targeting AMD64, but pedump is providing invalid information because it is being run in WOW64. That being said I still cannot load this library, if anyone has any suggestions they would be greatly appreciated.
One more thing I have tried: I made a new C# application and referenced the C++/CLI dll, then, in the main() function, I instantiated a class in the C++/CLI dll. This caused an access violation exception before the main() function is called. When I remove the instantiation, the main function runs fine. My guess is that the instantiation is causing a delay load of my C++/CLI assembly, which causes the same load error I was seeing from the native assembly.

Answer

Max Ehrlich picture Max Ehrlich · Feb 21, 2012

In case anyone runs across this error, it turned out that it was caused by my native libraries use of boost::threading. The boost::threading library uses some weird compilation settings. The result is a static library that is incompatible with clr or mixed-mode binaries. Of course, visual studio has no idea of this, so it happily links boost in and crashes when the dll is loaded.
The solution is to dynamically link in boost::threading. The easiest way to do this is to define BOOST_THREAD_DYN_LINK in your project settings. Once I defined that, the dll loaded fine.
A quick google search of C++/CLI boost threading will give plenty more information about this error