I've got a CLI code wrapping a C++ DLL.
When i try to compile it in debug mode, i get the following error:
Error 22 error LNK2022: metadata operation failed (8013118D) :
Inconsistent layout information induplicated types .... MSVCMRTD.lib (locale0_implib.obj)
The weird thing is that on Release mode it compiles OK and works OK.
The only difference i can see that causes the problem is when i change:
Configuration Properties -> C/C++ -> Code Generation -> Runtime Library
When it's set to: Multi-threaded Debug DLL (/MDd)
it throws the error.
When it's set to: Multi-threaded DLL (/MD)
it compiles fine.
The same settings work for all the other DLLs in the project (CLI and C++) and they inherit the same properties.
I'm using VS2010.
So, how can i solve this ?
And can I get some explanation to WHY this is happening ?
Update:
I've basically tried changing every option in the project's properties with no luck.
I've read somewhere that this might be caused from duplicate declarations of a type of the same name.
But in the CLI file i'm calling std::string etc. explicitly from std.
Any other ideas ?
Update:
A few error copy-pastes:
error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._String_val<char,std::allocator<char> >): (0x02000097). E:\MyProject....\MSVCMRTD.lib(locale0_implib.obj) DllName
error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._String_iterator<char,std::char_traits<char>,std::allocator<char> >): (0x02000091). E:\MyProject....\MSVCMRTD.lib(locale0_implib.obj) AnotherDllName
Note that the MSVCMRTD.lib file is actually a MS file used for compilation and isn't actually in my project (nor should be)
Update
If you this helps, here's the linker command line:
/OUT:"E:\blah.CLI.dll" /INCREMENTAL /NOLOGO /LIBPATH:"e:\blah\Output\" /LIBPATH:"E:\blah\lib_64" /LIBPATH:"blah\Lib_64\" /DLL "e:\Otheblaf.lib" /MANIFEST /ManifestFile:"x64\Debug\blah.CLI.dll.intermediate.manifest" /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"E:\blah.CLI.pdb" /SUBSYSTEM:WINDOWS /OPT:NOREF /OPT:NOICF /PGD:"E:\blah.CLI.pgd" /TLBID:1 /DYNAMICBASE:NO /FIXED:NO /MACHINE:X64 /ERRORREPORT:QUEUE
And the release that does work:
/OUT:"E:\blah.CLI.dll" /INCREMENTAL:NO /NOLOGO /LIBPATH:"E:\blah\" /LIBPATH:"E:\blah\Output\" /LIBPATH:"E:\blah\lib_64" /DLL "Configuration.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" "E:\blah.lib" /MANIFEST /ManifestFile:"blah.CLI.dll.intermediate.manifest" /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"E:\blah.CLI.pdb" /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /PGD:"E:\blah.CLI.pgd" /LTCG /TLBID:1 /DYNAMICBASE /FIXED:NO /MACHINE:X64 /ERRORREPORT:QUEUE
Finally got a solution:
In the end it was a problem in boost::lexical_cast<std:string>
There's a bug with .Net object using certain std:: objects. (in my case std::string as is shown in the error message).
This is because when they created this framework, they've re-invented some classes (std::string is one of them) but didn't do it properly in the debug version.
The class's signature is a bit different.
MSDN Related Article - Ambiguous References
So, the solution is to "hide" buggy classes from the .NET object.
Create a C++ level wrapper class that will wrap the original class's functions and cast the buggy class types to other class types that compile correctly.
Make sure that in the wrapper class's header there's no references or includes to the buggy class type. (Can be done with careful Forward reference/decleration)
With VS2010 you can compile the unmanaged wrapper .cpp file explicitly without /clr.
Then you can use the wrapper class properly with the managed ref class.
Another option
replace lexical_cast<std::string>
with:
ostringstream os;
os << i;
return os.str();