LNK2022和LNK2034链接器错误与CRT版本10.0

时间:2011-04-06 22:49:29

标签: windows visual-studio-2010 winapi stl linker-errors

很抱歉打扰这个问题的任何人,但我已经研究了几个小时,还没有决议:

我正在将一个相当庞大的应用程序移植到Visual Studio 2010中的10.0 CRT(编译器)。该应用程序是使用/ clr管理的C ++ / CLI。大多数代码都是本机代码(95%),其中包含一些托管部分。

所以我的工作是在.vcxproj中切换以定位较新的10.0 CRT(即编译器)。我们之前使用的是v90,或者使用VS 2008 SP1附带的VC编译器。

好的,那么突破性变化?实际上看起来像一堆。我修复了一些处理集合的迭代器问题,这一切都非常简单。

但是这些链接器错误正在扼杀我。任何帮助将不胜感激:

1>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (80131195) : Custom attributes are not consistent: (0x0c0001c0).
1>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (80131195) : Custom attributes are not consistent: (0x0c0001c5).
...

1>MSVCMRTD.lib(locale0_implib.obj) : error LNK2034: metadata inconsistent with COFF symbol table: symbol '??0?$allocator@D@std@@$$FQAE@ABV01@@Z' (06000141) has inconsistent metadata with (0A000F75) in identity.obj
1>MSVCMRTD.lib(locale0_implib.obj) : error LNK2034: metadata inconsistent with COFF symbol table: symbol '??0?$allocator@D@std@@$$FQAE@ABV01@@Z' (06000141) has inconsistent metadata with (0A000F76) in ICustAttribCollapseManagerImp.obj
... (repeated hundreds of times)

我继续前进,未修饰符号:

??0?$allocator@D@std@@$$FQAE@ABV01@@Z

得到了:

public: __thiscall std::allocator<char>::allocator<char>(class std::allocator<char> const &)

所以,据我所知,msvcmrtd.lib文件以一种方式编译了这个std :: allocator,而我的项目设置中的其他东西(#pragma managed ??)是以另一种不同的方式编译的。但如果是这样,我该寻找什么?多年来,使用旧的编译器编译好了。

注意: 我们目前是3.5 .NET框架(不确定这是否有帮助......我对此表示怀疑)

由于

5 个答案:

答案 0 :(得分:3)

这是一个难以诊断的问题,链接器错误很糟糕,并且记录很少。有一篇文章来自微软的STL维护人员Stephan Lavavej在页面底部的this thread中的帖子。我不得不说,除了尝试在项目设置中禁用迭代器调试(预处理器定义中的_HAS_ITERATOR_DEBUGGING = 0)之外,我没有看到任何建议。

您需要考虑代码审核。确实看起来您正在将STL代码编译为托管代码。这一般起作用(减去链接器的麻烦),但它确实是错误的。将STL集合类保留为本机代码,在托管代码中使用BCL集合类(List&lt;&gt;等)。

答案 1 :(得分:2)

就我而言,有助于将.VCXPROJ中的TargetFramework更改为:

<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>

但正如你所提到的,你需要针对3.5进行编译,我不确定在这种情况下你能做些什么。

答案 2 :(得分:0)

我最近将一个VS2008项目迁移到VS2012,其中包括一个C ++ / cli项目,并且遇到了这些错误。当涉及到我的项目/构建文件时,我非常肛门保持,所以我设置了一些自定义项目所有导入的自定义.props msbuild文件(以避免msbuild XML中的所有重复和条件谜题元素)。

假设该项目是Example.vcxproj。并且在一开始我就有了这个:

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
  <ConfigurationType>DynamicLibrary</ConfigurationType>
  <PlatformToolset>v110_xp</PlatformToolset>
  <CharacterSet>Unicode</CharacterSet>
  <CLRSupport>true</CLRSupport>
  <-- Including this here fixed my linker problems -->
  <!--<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>-->
</PropertyGroup>
...
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
...
<Import Project="$(SolutionDir)..\shared\config\msbuild\FileWithCommonSettings.props" />

我的FileWithCommonSettings.props文件(我将-TargetFrameworkVersion定义)包含在-after-Microsoft.Cpp.props中。我改为尝试在Cpp.props之前尝试设置-TargetFrameworkVersion,正如您在注释掉的XML中看到的那样。这样做解决了我遇到的所有链接器问题。我的猜测是,在VS2010及更高版本中,Cpp.Default.props默认为v4.0。

希望这有帮助

编辑Refering to this social.msdn thread,您似乎需要使用VS2010(即工具集v100)才能真正定位v3.5。我没有意识到我仍然使用vc110默默地瞄准4.0 ...但是只有在我添加-TargetFrameworkVersion-元素之后我才摆脱了链接器错误。切换到vc100工具集后,链接器错误又回来了。

答案 3 :(得分:0)

虽然我对这个问题的解决方案并没有解决为什么会发生这种情况,但我注意到我的意见,以防其他人遇到同样的情况。

我也收到了编译我的clr项目的类似错误。我的目标是将我的版本升级到11.0,但保留.NET framework 2.0作为目标。就我而言,我看到了Lnk2034和lnk2020错误(与上面提到的lnk2022不同)。

1>MSVCMRTD.lib(locale0_implib.obj) : error LNK2034: metadata inconsistent with COFF symbol table: symbol '?_Facet_Register_m@std@@$$FYAXPAV_Facet_base@1@@Z' (06000068) has inconsistent metadata with (0A000C23) in DirectSystemAccessProxy.obj
1>LINK : error LNK2034: metadata inconsistent with COFF symbol table: symbol '??3@$$FYAXPAX@Z' (060003CB) has inconsistent metadata with (0A00009D) in MSVCMRTD.lib(locale0_implib.obj)
...
1>myProject.obj : error LNK2020: unresolved token (0A000C23) "void __cdecl std::_Facet_Register_m(class std::_Facet_base *)" (?_Facet_Register_m@std@@$$FYAXPAV_Facet_base@1@@Z)
1>MSVCMRTD.lib(locale0_implib.obj) : error LNK2020: unresolved token (0A0000C4) "extern "C" void __cdecl free(void *)" (?free@@$$J0YAXPAX@Z)
...

最初,我通过纠正本项目中本机容器的使用来遵循Hans Passat的建议。我注释掉了这些容器的所有实例,以验证它们确实是失败的原因。

在调查过程中,我发现以下行导致了我的错误:

std::wstringstream wstream;
wstream << " Failed to to do something \'" << var << "\'.";

当我将其更正为以下时,这些错误消失了。

std::wstringstream wstream;
wstream << L" Failed to to do something \'" << var << L"\'."; // Added wide string literal.

不知道为什么这样的行会导致这种行为,但确实如此。

旁注:

  • 针对更高的.NET框架(4.0)也很有效,但我想坚持以2.0的原始.NET框架为目标。
  • 我的项目没有预先记录器定义:_HAS_ITERATOR_DEBUGGING = 0.根据我的理解,不再支持在/ clr中编译_HAS_ITERATOR_DEBUGGING(参见Hans Passat回答中的链接)

答案 4 :(得分:0)

对于像我这样的人来说这个答案没有帮助,第二个选择是去: 项目属性 - &gt;配置属性 - &gt;常规 - &gt;项目默认值 - &gt; .NET目标框架版本并将其设置为 v4.0

https://connect.microsoft.com/VisualStudio/feedbackdetail/view/806238/unwarranted-linker-errors-using-stl-filestream-class-in-managed-classes-in-c-11-cli有一个来自微软团队的晦涩难懂的答案,解决了我的问题。