Compiler construction 编译调试模式时出错:C++/CLI-错误LNK2022 我有一个包装C++的DLL代码。 当我尝试在调试模式下编译它时,出现以下错误:

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++),它们继承相同的属性

错误22错误LNK2022:元数据操作失败(8013118D):

不一致的布局信息包含复杂的类型。。。。MSVCMRTD.lib(locale0_implib.obj)

奇怪的是,在发布模式下,它编译正常,工作正常。
我所能看到的导致问题的唯一区别是当我改变时:

配置属性->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位时,出现了链接错误。我的修复是配置正确