linkerc++-clilinker-errorsclr

Getting error when compiling debug mode: C++/CLI - error LNK2022


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


Solution

  • 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();