Compiler construction 编译调试模式时出错:C++/CLI-错误LNK2022 我有一个包装C++的DLL代码。 当我尝试在调试模式下编译它时,出现以下错误:
错误22错误LNK2022:元数据操作失败(8013118D): 不一致的布局信息包含复杂的类型。。。。MSVCMRTD.lib(locale0_implib.obj) 奇怪的是,在发布模式下,它编译正常,工作正常。Compiler construction 编译调试模式时出错:C++/CLI-错误LNK2022 我有一个包装C++的DLL代码。 当我尝试在调试模式下编译它时,出现以下错误:,compiler-construction,linker,c++-cli,clr,linker-errors,Compiler Construction,Linker,C++ Cli,Clr,Linker Errors,错误22错误LNK2022:元数据操作失败(8013118D): 不一致的布局信息包含复杂的类型。。。。MSVCMRTD.lib(locale0_implib.obj) 奇怪的是,在发布模式下,它编译正常,工作正常。 我所能看到的导致问题的唯一区别是当我改变时: 配置属性->C/C++->代码生成->运行库 当设置为:多线程调试DLL(/MDd)时,将抛出错误。 当它设置为:多线程DLL(/MD)时,它可以很好地编译 相同的设置适用于项目中的所有其他DLL(CLI和C++),它们继承相同的属性
我所能看到的导致问题的唯一区别是当我改变时: 配置属性->C/C++->代码生成->运行库 当设置为:
多线程调试DLL(/MDd)
时,将抛出错误。当它设置为:
多线程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
错误LNK2022:元数据操作失败(8013118D):重复类型中的布局信息不一致(标准字符串值):(0x02000097)。E:\MyProject….\MSVCMRTD.lib(locale0_implib.obj)DllName
错误LNK2022:元数据操作失败(8013118D):重复类型中的布局信息不一致(标准字符串迭代器):(0x02000091)。E:\MyProject..\MSVCMRTD.lib(locale0_implib.obj)另一个dllname
请注意,MSVCMRTD.lib文件实际上是一个用于编译的MS文件,实际上不在我的项目中(也不应该是)
更新
如果您认为这有帮助,下面是链接器命令行:
/输出:“E:\blah.CLI.dll”/INCREMENTAL
/NOLOGO/LIBPATH:“e:\blah\Output\”
/LIBPATH:“E:\blah\lib_64”
/LIBPATH:“blah\Lib_64\”/DLL
“e:\Otheblaf.lib”/MANIFEST
/清单文件:“x64\Debug\blah.CLI.dll.intermediate.manifest”
/ALLOWISOLATION
/宣言:“level='asInvoker'
uiAccess='false'”/DEBUG
/PDB:“E:\blah.CLI.PDB”
/子系统:WINDOWS/OPT:NOREF
/选项:NOICF/PGD:“E:\blah.CLI.PGD”
/TLBID:1/动态数据库:否/固定:否
/计算机:X64/ERRORREPORT:队列
而真正起作用的版本是:
/输出:“E:\blah.CLI.dll”/INCREMENTAL:NO
/NOLOGO/LIBPATH:“E:\blah\”
/LIBPATH:“E:\blah\Output\”
/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
/清单文件:“blah.CLI.dll.intermediate.manifest”
/ALLOWISOLATION
/宣言:“level='asInvoker'
uiAccess='false'”/DEBUG
/PDB:“E:\blah.CLI.PDB”
/子系统:WINDOWS/OPT:REF/OPT:ICF
/PGD:“E:\blah.CLI.PGD”/LTCG/TLBID:1
/动态数据库/固定:否/机器:X64
/错误报告:队列
在编译到调试模式之前,请确保清理生成。我希望这将对您有所帮助。 在本例中,MSDN建议对对象文件运行“ildasm–tokens”,以查找哪些类型的令牌列在错误消息中,并查找差异
ildasm exe上有一些输入。在构建项目时,是否使用自定义生成文件或自定义编译器参数?这可能会以难以想象的方式破坏项目 [a] 在构建该DLL期间,可能将pragma pack设置设置为自定义编译器设置,从而导致windows标准标头中的结构被错误打包,从而导致大小不匹配。容易修理。。检查cl.exe的-Zp设置
这种情况可能会解决结构是您自己的自定义结构或类之一的情况 [b] 另一种可能发生这种情况的情况是,其中一个头文件包含windows标准头文件,并且pragma包尚未还原。然后,这会将不正确的包信息传播到标准标头,从而导致与上述问题相同的问题。通常很容易解决,首先包括所有(过于简化的方式)窗口标题,以便稍后跳过它们
希望这有帮助。终于找到了解决方案: 最后,它在
boost::lexical_cast
.Net对象使用某些std::对象时出现错误。(在我的例子中,std::string如错误消息所示)
这是因为当他们创建这个框架时,他们已经发明了一些类(std::string就是其中之一),但在调试版本中没有正确地实现它。这个类的签名有点不同 MSDN相关文章- 因此,解决方案是对.NET对象“隐藏”有缺陷的类 < P>创建一个C++级别包装器类,它将包装原始类的函数并将其转换为 错误的类类型转换为正确编译的其他类类型 确保包装类的头中没有对buggy类类型的引用或包含。(可小心操作)
使用VS2010,您可以在不使用/clr的情况下显式编译非托管包装器.cpp文件 然后可以将包装器类与托管ref类一起正确使用 另一个选项 将
lexical_cast
替换为:
ostringstream os;
os << i;
return os.str();
ostringstreamos;
我发现我的项目中使用的WINVER与我链接到的库中使用的WINVER不同。同步这些常量为我解决了问题。当我将项目转换为64位时,出现了链接错误。我的修复是配置正确