编译调试模式时出错:C ++ / CLI - 错误LNK2022

时间:2011-01-30 09:43:20

标签: compiler-construction linker c++-cli clr linker-errors

我有一个包装C ++ DLL的CLI代码 当我尝试在调试模式下编译它时,我收到以下错误:

  

错误22错误LNK2022:元数据操作失败(8013118D):

     

不一致的布局信息复杂类型.... MSVCMRTD.lib(locale0_implib.obj)

奇怪的是,在发布模式下,它编译正常并且正常工作 我可以看到导致问题的唯一区别是当我改变时:

配置属性 - > C / C ++ - >代码生成 - >运行时库

当它设置为:Multi-threaded Debug DLL (/MDd)时,它会抛出错误 当它设置为:Multi-threaded DLL (/MD)时,它编译得很好。

相同的设置适用于项目中的所有其他DLL(CLI和C ++),并且它们继承了相同的属性。

我正在使用VS2010。

那么,我该如何解决这个问题?

我能否解释为什么会发生这种情况?

更新

我基本上试图改变项目属性中的每个选项而没有运气。

我在某处读到过这可能是由于同名类型的重复声明造成的 但是在CLI文件中我明确地从std。

调用std :: string等
  • 重命名对象不起作用

还有其他想法吗?

更新

一些错误的复制粘贴:

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

请注意, MSVCMRTD.lib 文件实际上是用于编译的MS文件,实际上并不在我的项目中(也不应该)

更新

如果这有帮助,这里是链接器命令行:

  

/ OUT:“E:\ blah.CLI.dll”/ INCREMENTAL   / NOLOGO / LIBPATH:“e:\ blah \ Output \”   / LIBPATH: “E:\等等\ lib_64”   / LIBPATH:“blah \ Lib_64 \”/ DLL   “e:\ Otheblaf.lib”/ MANIFEST   /ManifestFile:"x64\Debug\blah.CLI.dll.intermediate.manifest”   / ALLOWISOLATION   / MANIFESTUAC:“电平= '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

有效的版本:

  

/ OUT:“E:\ blah.CLI.dll”/ INCREMENTAL:NO   / NOLOGO / LIBPATH:“E:\ blah \”   / LIBPATH: “E:\等等\输出\”   / 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:“电平= '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

6 个答案:

答案 0 :(得分:2)

您在构建项目时是使用自定义生成文件还是自定义编译器参数?这可能会以难以想象的方式搞乱项目。

[a]在构建该DLL期间,pragma pack设置可能被设置为自定义编译器设置,这导致windows标准头中的结构被错误地打包导致大小不匹配。易于修复..检查cl.exe的-Zp设置
这种情况可以解决结构是您自己的自定义结构或类之一的情况。

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

[b]另一种可能发生这种情况的情况是,其中一个头文件包含windows standrd头文件并且pragma pack尚未恢复。然后,这将错误的包信息传播到标准标题,导致与上述相同的问题。通常很容易通过首先包含所有(通过简化方式)窗口标题来解决,以便稍后跳过它们。

希望这有帮助。

答案 1 :(得分:1)

终于得到了解决方案:

最后,这是boost::lexical_cast<std:string>

中的一个问题

.Net对象使用某些 std :: 对象时出现错误。 (在我的例子中,错误消息中显示了std :: string)。

这是因为当他们创建这个框架时,他们重新发明了一些类(std :: string就是其中之一)但是在调试版本中没有正确地完成它。
班级的签名有点不同。

MSDN相关文章 - Ambiguous References

因此,解决方案是从.NET对象中“隐藏”错误的类。

创建一个C ++级别的包装类,它将包装原始类的函数并强制转换 错误的类类型到正确编译的其他类类型。

确保在包装器类的头文件中没有引用或包含错误的类类型。 (可以谨慎Forward reference/decleration)来完成 使用VS2010,您可以在没有/ clr的情况下显式编译非托管包装.cpp文件。

然后,您可以使用托管ref类正确使用包装器类。

另一个选项

lexical_cast<std::string>替换为:

ostringstream os;
os << i;
return os.str();

答案 2 :(得分:0)

当我将项目转换为64位时,我遇到了这个链接错误。我的修复是配置属性&gt; C / C ++ &gt; 代码生成&gt; 结构成员对齐&gt; 16字节(/ Zp16)

答案 3 :(得分:-1)

确保在编译到调试模式之前清理构建。

答案 4 :(得分:-1)

我希望link对您有所帮助。 在此MSDN建议在目标文件上运行'ildasm -tokens'以查找哪些类型具有error_message中列出的标记,并查找差异。

Here是ildasm exe的一些输入。

答案 5 :(得分:-1)

我发现我的项目中使用的WINVER与我链接的库中使用的WINVER不同。同步这些常量为我解决了这个问题。