我有一个 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
我已经阅读了几乎所有我能找到的关于这个问题的帖子并尝试过:
- 清理并重建
-
移动标题 https://stackoverflow.com/questions/3909470/lnk2022-error-when-using-clr- 没有对 windows.h 的引用,我尝试移动 #include 行但没有效果
-
仅在需要它的文件上使用 /clr 标志 https://stackoverflow.com/questions/11990095/lnk2022-metadata-operation-inconsistent-layout-information-in-duplicated-types在 Wrapper.DLL 中(这恰好是项目中的所有文件)。问题在于,Wrapper.DLL 需要调用的 Native.DLL 中的公共方法在其签名中包含 std:string 参数。这使得很难将 STL 引用从 /clr 编译的范围中分离出来
- 我正在编译所有内容(包括 ITK、第 3 方库)与/MDd(并尝试过/MD)-更改此设置似乎不会影响事情
- 我没有看到/Zp 或杂注包在任何地方使用
我能想到的唯一“解决方案”是更改 Native.DLL 中的方法,不使用 std:string 作为参数(例如,使用 char* 代替)。然而,避免在任何 C++/CLI 包装器中使用 STL 似乎并不是一个解决方案。那里must是一个更好的方式!
注意:我知道有关如何“调试”这些问题的文章(link http://blogs.msdn.com/b/vcblog/archive/2007/05/17/diagnosing-hidden-odr-violations-in-visual-c-and-fixing-lnk2022.aspx),但除非我弄错了,否则我想我知道问题的根源是 std:string。