LNK 2022:迁移到VS2010后布局信息不一致 [英] LNK 2022: Inconsistent layout information, after migrating to VS2010

查看:1648
本文介绍了LNK 2022:迁移到VS2010后布局信息不一致的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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




  • Native.DLL链接到第三方库lib,ITK,其中包括STL)



伪代码(非常简化):

 使用namespace std; 

bool Native :: CalcSomething(double * result,string& errorMsg);




  • Wrapper.DLL(C ++ / CLI项目,动态链接到Native。 DLL并在调用Native.DLL时使用std:string)



伪代码(非常简化)

  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>生成代码... 
2> MSVCMRTD.lib(locale0_implib.obj):error LNK2022:元数据操作失败(8013118D):重复类型(std.logic_error)中的布局信息不一致(std.logic_error):(0x02000049)。
2> MSVCMRTD.lib(locale0_implib.obj):error LNK2022:元数据操作失败(8013118D):重复类型(std.domain_error)中的布局信息不一致:(0x0200004a)。
2> MSVCMRTD.lib(locale0_implib.obj):error LNK2022:元数据操作失败(8013118D):重复类型(std.invalid_argument):(0x0200004b)中布局信息不一致。
2> MSVCMRTD.lib(locale0_implib.obj):error LNK2022:元数据操作失败(8013118D):重复类型(std.length_error)中的布局信息不一致:(0x0200004c)。
2> MSVCMRTD.lib(locale0_implib.obj):error LNK2022:元数据操作失败(8013118D):重复类型(std.out_of_range)中的布局信息不一致:(0x0200004d)。
2> MSVCMRTD.lib(locale0_implib.obj):error LNK2022:元数据操作失败(8013118D):重复类型(std.runtime_error)中的布局信息不一致:(0x0200004e)。
2> MSVCMRTD.lib(locale0_implib.obj):error LNK2022:元数据操作失败(8013118D):重复类型中的布局信息不一致(std.overflow_error):(0x02000050)。
2> MSVCMRTD.lib(locale0_implib.obj):error LNK2022:元数据操作失败(8013118D):重复类型(std.underflow_error)中的布局信息不一致:(0x02000051)。
2> MSVCMRTD.lib(locale0_implib.obj):error LNK2022:元数据操作失败(8013118D):重复类型(std.range_error)中的布局信息不一致:(0x02000052)。
2> MSVCMRTD.lib(locale0_implib.obj):error LNK2022:元数据操作失败(8013118D):重复类型(std._Locinfo)中的布局信息不一致:(0x02000054)。
2> MSVCMRTD.lib(locale0_implib.obj):error LNK2022:元数据操作失败(8013118D):重复类型(_Locimp)中的布局信息不一致:(0x02000059)。
2> MSVCMRTD.lib(locale0_implib.obj):error LNK2022:元数据操作失败(8013118D):重复类型(失败)中布局信息不一致:(0x02000068)。
2> MSVCMRTD.lib(locale0_implib.obj):error LNK2022:元数据操作失败(8013118D):重复类型中的布局信息不一致(std._String_val< char,std :: allocator< char> 0x02000097)。
2> MSVCMRTD.lib(locale0_implib.obj):error LNK2022:元数据操作失败(8013118D):重复类型中的布局信息不一致(std._String_val< wchar_t,std :: allocator< wchar_t>>): 0x02000099)。
2> MSVCMRTD.lib(locale0_implib.obj):error LNK2022:元数据操作失败(8013118D):重复类型(lconv)中的布局信息不一致:(0x020000ce)。
2> LINK:致命错误LNK1255:链接由于元数据错误而失败

几乎每个我可以在这个问题上找到并试过了的线程:




  • 清理并重建

  • a href =http://stackoverflow.com/questions/3909470/lnk2022-error-when-using-clr>移动标题周围 - 没有对windows.h的引用,我已经尝试移动#include line around to no effect

  • 在Wrapper.DLL中使用/ clr标志只对需要它的文件(这恰好是项目中的所有文件)。问题是,需要由Wrapper.DLL调用的Native.DLL中的public方法在其签名中包含一个std:string参数。这使得难以将STL引用与/ clr编译范围分开

  • 我正在编译所有内容(包括ITK,第三方库) with / MDd < 在任何地方都可以使用 / Zp或pragma pack / li>


我可以想到的唯一解决方案是将Native.DLL中的方法更改为不使用std:string作为参数例如,使用char *)。但是,避免在任何C ++ / CLI包装中使用STL几乎看起来不是一个解决方案。

必须

是更好的方式!



注意:我知道有关如何调试这些问题的文章http://blogs.msdn.com/b/vcblog/archive/2007/05/17/diagnosing-hidden-odr-violations-in-visual-c-and-fixing-lnk2022.aspx =nofollow > link ),但除非我错了,我想我知道问题的根源是std:string。

解决方案<



我在一个CMake文件中做了一个语法改变,我认为它在功能上与之前发生的一样基本上我是使用一个CMake方便的变量)。但是,这当然会有意想不到的后果,因此产生的项目文件不一样。



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



更改CMake回来并正确生成项目后,可怕的LNK2022消失了。我只有自己责怪所有那些时间浪费...


I have a VS2010 solution that contains (among others), the following projects:

  • Native.DLL (native C++ project that statically links to a third party lib, ITK, which includes STL)

Pseudo-code (very simplified):

using namespace std;

bool Native::CalcSomething(double* result, string& errorMsg);

  • Wrapper.DLL (C++/CLI project that dynamically links to Native.DLL and uses std:string in a call to the Native.DLL)

Pseudo-code (very simplified)

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;
}

This compiled and linked perfectly in VS2008 (x64), but after migrating to VS2010 (for various reasons), the linker gives the following errors:

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

I have read almost every thread I could find on this issue and have tried:

  • Clean and rebuild
  • Move the headers around - there is no reference to windows.h and I have tried moving the #include line around to no effect
  • Using the /clr flag only on the files that need it in Wrapper.DLL (this happens to be all the files in the project). The problem is that the public method in Native.DLL that needs to be invoked by Wrapper.DLL includes a std:string parameter in its signature. This makes it difficult to separate the STL reference out from the scope of the /clr compilation
  • I am compiling everything (including ITK, the 3rd party lib) with /MDd (and have tried /MD) - changing this setting does not seem to affect things
  • I do not see /Zp or pragma pack being used anywhere

The only "solution" I can think of is to change the method in Native.DLL to not use std:string as a parameter (e.g. use char* instead). However, to avoid the use of STL in any C++/CLI wrappers hardly seems like a solution. There must be a better way!

Note: I am aware of the article on how to "debug" these issues (link), but unless I'm mistaken, I think I know the source of the issue is the std:string.

解决方案

I figured it out.

I had made a syntax change in one of the CMake files that I thought to be functionally identical to what was happening before (essentially I was using a CMake convenience variable). However, this of course had unintended consequences and the resulting project files were NOT the same.

Specifically, the Wrapper.DLL project was now linking to the 3rd party ITK libs that it did not need to link to at all (only the Native.DLL needs these).

After changing the CMake back and generating the project correctly, the dreaded LNK2022 went away. I only have myself to blame for all those hours wasted...

这篇关于LNK 2022:迁移到VS2010后布局信息不一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆