【问题标题】:LNK 2022: Inconsistent layout information, after migrating to VS2010LNK 2022:迁移到 VS2010 后布局信息不一致
【发布时间】:2013-04-01 14:55:01
【问题描述】:

我有一个 VS2010 解决方案,其中包含(除其他外)以下项目:

  • Native.DLL(静态链接到第三方库 ITK 的本地 C++ 项目,其中包括 STL)

伪代码(非常简化):

using namespace std;

bool Native::CalcSomething(double* result, string& errorMsg);
  • Wrapper.DLL(动态链接到 Native.DLL 并在调用 Native.DLL 时使用 std:string 的 C++/CLI 项目)

伪代码(非常简化)

bool Wrapper::WrappedCalcSomething([System::Runtime::InteropServices::OutAttribute] double[] result,[System::Runtime::InteropServices::OutAttribute] System::String^ errorMsg)
{
   Native* ntv = new Native();

   std:string error;
   pin_ptr<double> resultPtr = &result[0];

   bool success = ntv->CalcSomething(resultPtr, error);

   errorMsg = gcnew System::String(error.c_str());

   return success;
}

这在 VS2008 (x64) 中完美编译和链接,但是在迁移到 VS2010 后(由于各种原因),链接器给出以下错误:

2>  Generating Code...
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.logic_error): (0x02000049).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.domain_error): (0x0200004a).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.invalid_argument): (0x0200004b).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.length_error): (0x0200004c).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.out_of_range): (0x0200004d).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.runtime_error): (0x0200004e).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.overflow_error): (0x02000050).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.underflow_error): (0x02000051).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.range_error): (0x02000052).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._Locinfo): (0x02000054).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (_Locimp): (0x02000059).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (failure): (0x02000068).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._String_val<char,std::allocator<char> >): (0x02000097).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._String_val<wchar_t,std::allocator<wchar_t> >): (0x02000099).
2>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (lconv): (0x020000ce).
2>LINK : fatal error LNK1255: link failed because of metadata errors

我已经阅读了几乎所有我能找到的关于这个问题的帖子并尝试过:

  • 清理并重建
  • Move the headers around - 没有对 windows.h 的引用,我尝试移动 #include 行但没有效果
  • Wrapper.DLL 中的Using the /clr flag only on the files that need it(这恰好是项目中的所有文件)。问题是 Native.DLL 中需要被 Wrapper.DLL 调用的公共方法在其签名中包含一个 std:string 参数。这使得很难将 STL 引用从 /clr 编译的范围中分离出来
  • 我正在编译所有内容(包括 ITK、第 3 方库)使用 /MDd(并尝试过 /MD)- 更改此设置似乎不会影响事情
  • 我没有看到 /Zp 或 pragma pack 在任何地方使用

我能想到的唯一“解决方案”是将 Native.DLL 中的方法更改为不使用 std:string 作为参数(例如,改用 char*)。然而,避免在任何 C++/CLI 包装器中使用 STL 似乎不是一个解决方案。 必须有更好的方法!

注意:我知道有关如何“调试”这些问题的文章 (link),但除非我弄错了,否则我想我知道问题的根源是 std:string。

【问题讨论】:

  • 你是否也重建了wrapper.dll
  • 是的,每当我尝试新的“修复”时,我都会重建本机项目和包装器项目。
  • 您是如何迁移项目的?刚刚从 VS2008 自动转换过来的?
  • 我们使用 CMake 来生成我们的 VS 项目和解决方案文件。所以我将 CMake 目标从“Visual Studio 9 Win 64”更改为“Visual Studio 10 Win64”。生成的解决方案文件无需通过转换向导即可使用。
  • 好吧,我会在这里使用分而治之。没有比手动创建解决方案/项目并开始向其中添加项目并在每个步骤中检查它是否正确构建更好的方法

标签: c++ visual-studio-2010 c++-cli lnk2022


【解决方案1】:

我想通了。

我对其中一个 CMake 文件进行了语法更改,我认为该文件在功能上与之前发生的相同(本质上我使用的是 CMake 便利变量)。但是,这当然会产生意想不到的后果,并且生成的项目文件并不相同。

具体来说,Wrapper.DLL 项目现在链接到它根本不需要链接的第 3 方 ITK 库(只有 Native.DLL 需要这些库)。

改回 CMake 并正确生成项目后,可怕的 LNK2022 消失了。浪费了这么多时间,只能怪我自己……

【讨论】:

  • 啊,看来你还是想通了!
猜你喜欢
  • 1970-01-01
  • 2019-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-09
  • 1970-01-01
  • 2014-11-28
  • 1970-01-01
相关资源
最近更新 更多