Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

  • Renaming the objects didn't work

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

like image 581
Yochai Timmer Avatar asked Jun 15 '26 03:06

Yochai Timmer


2 Answers

Are you using custom make-files or customized compiler paramterers when building the projects? This could screw with projects in unimaginable ways.

[a] It is possible that the pragma pack setting during the building of that DLL was set as custom compiler setting which caused the structures in windows standard headers to be packed incorrectly causing the mismatch in sizes. Easy to fix .. check for -Zp settings for cl.exe
This situation may solve cases where the structure is one of your own custom structures or classes.

http://msdn.microsoft.com/en-us/library/xh3e3fd0%28v=VS.71%29.aspx

[b] Another case where this can happen is when one of the header files is including windows standrd headers and the pragma pack hasn't been restored. This then propogates the incorrect pack info to the standard headers causing same problems as above. Generally easy to solve by including all (over simplified way tho) windows headers first so they get skipped later on.

Hope this helps.

like image 197
chkdsk Avatar answered Jun 17 '26 23:06

chkdsk


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();
like image 43
Yochai Timmer Avatar answered Jun 17 '26 23:06

Yochai Timmer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!