【问题标题】:Getting error when compiling debug mode: C++/CLI - error LNK2022编译调试模式时出错:C++/CLI - 错误 LNK2022
【发布时间】:2011-06-18 01:14:13
【问题描述】:

我有一个包装 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:\blah\lib_64" /LIBPATH:"blah\Lib_64\" /DLL “e:\Otheblaf.lib”/清单 /ManifestFile:"x64\Debug\blah.CLI.dll.intermediate.manifest" /允许隔离 /MANIFESTUAC:"level='asInvoker' uiAccess='假'" /DEBUG /PDB:"E:\blah.CLI.pdb" /子系统:WINDOWS /OPT:NOREF /OPT:NOICF /PGD:"E:\blah.CLI.pgd" /TLBID:1 /DYNAMICBASE:NO /FIXED:NO /机器:X64 /错误报告:队列

以及有效的版本:

/OUT:"E:\blah.CLI.dll" /INCREMENTAL:NO /NOLOGO /LIBPATH:"E:\blah\" /LIBPATH:"E:\blah\输出\" /LIBPATH:"E:\blah\lib_64" /DLL “配置.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”/清单 /ManifestFile:"blah.CLI.dll.intermediate.manifest" /允许隔离 /MANIFESTUAC:"level='asInvoker' uiAccess='假'" /DEBUG /PDB:"E:\blah.CLI.pdb" /子系统:WINDOWS /OPT:REF /OPT:ICF /PGD:"E:\blah.CLI.pgd" /LTCG /TLBID:1 /DYNAMICBASE /FIXED:NO /MACHINE:X64 /错误报告:队列

【问题讨论】:

  • 你已经问过这个了,确切同样的问题。从那以后你肯定发现了别的东西吗?
  • 不,没有任何答案,我想我会重新提出这个问题。我还没有找到解决办法。 (并且“只需使用 /MD 就可以编译”)不是答案。
  • 这个答案有帮助吗? stackoverflow.com/questions/810827/… - 我正在努力寻找从哪里开始。
  • 我试过删除“增量构建”...没有用。谢谢
  • 这是另一个处理几乎相同问题的 SO 帖子:stackoverflow.com/questions/3909470/…,也许那里的答案会对您有所帮助。

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


【解决方案1】:

在构建项目时,您是否使用自定义 make 文件或自定义编译器参数?这可能会以难以想象的方式破坏项目。

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

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

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

希望这会有所帮助。

【讨论】:

  • 在有问题的 CLI 头文件中包含标准 windows std 头实际上在我的一个 CLI 项目中确实有效。
  • 我在使用 CLR 项目中的 C++ libjson 时遇到了这个问题。禁用 JSON_LESS_MEMORY(设置编译指示包)修复了它。谢谢!
【解决方案2】:

终于有办法了:

最后还是boost::lexical_cast&lt;std:string&gt;出了问题

.Net 对象使用某些 std:: 对象存在错误。 (在我的情况下,std::string 显示在错误消息中)。

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

MSDN 相关文章 - Ambiguous References

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

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

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

然后您可以将包装类与托管引用类正确使用。

另一种选择

lexical_cast&lt;std::string&gt; 替换为:

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

【讨论】:

    【解决方案3】:

    我将项目转换为 64 位时出现此链接错误。我的修复是配置属性 > C/C++ > 代码生成 > 结构成员对齐 > 16字节(/Zp16)

    【讨论】:

    • OP(原始海报)已经在另一个地方找到了解决方案。这对问题的理解增加了什么?它如何与给定的解决方案一起工作?当你重新开始讨论时,你应该提供理由和对比。
    • 那很危险。您正在更改项目中所有结构的对齐方式。这意味着链接到该项目的任何其他项目都需要以相同的方式进行编译。这将是非常严格的。
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

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

      Here 是 ildasm exe 的一些输入。

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          猜你喜欢
          • 2013-07-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-25
          • 1970-01-01
          相关资源
          最近更新 更多