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



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

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

所以我的工作是在。vcxproj中切换到新的10.0 CRT(即编译器)。我们之前使用的是v90,或者使用vs2008 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框架(不确定这是否有帮助……我对此表示怀疑)

谢谢

这是一个很难诊断的问题,链接器错误很糟糕,而且文档记录很差。微软的STL维护者Stephan Lavavej在页面底部的这个线程中发表了一篇关于它的帖子。我不得不说,除了试图在项目设置中禁用迭代器调试(预处理器定义中的_HAS_ITERATOR_DEBUGGING = 0)之外,我没有看到太多的建议。

您确实需要考虑代码审查。看起来确实像是在将STL代码编译为托管代码。这在一般情况下(减去链接器的麻烦),但这真的是错误的事情。将STL集合类留给您的本机代码,在托管代码中使用BCL集合类(List<>等)。

对于像我这样的人来说,这个答案听起来没有帮助,第二个选择是去:项目属性->配置属性->常规->项目默认值->。. 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有一个来自微软团队的模糊答案,解决了我的问题。

在我的情况下,帮助是将。vcxproj中的TargetFramework更改为:

<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>

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

我最近将一个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)..sharedconfigmsbuildFileWithCommonSettings.props" />

我有我的FileWithCommonSettings。props文件(我有- targetframeworkversion - defined)被包含在- microsoft . cp .props之后。我选择在Cpp之前尝试设置- targetframeworkversion。正如您在注释掉的XML中看到的那样。这样做修复了我得到的所有链接器问题。我的猜测是,在VS2010和更高版本中,Cpp.Default.props默认为v4.0。

希望有帮助

edit:指的是这个社会。msdn线程,看来你需要使用VS2010(即,工具集v100),以实际目标v3.5。我没有意识到我默默地瞄准4.0仍然与vc110…但只有在我添加了- targetframeworkversion -元素后,我才摆脱了链接器错误。切换到vc100工具集后,链接器错误又出现了

虽然我对这个问题的解决方案没有解决为什么会发生这种情况,但我记下了我的观察结果,以防其他人遇到同样的情况。

我也收到了类似的错误编译我的clr项目。我的目标是将我的版本升级到11.0,但保留。net框架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)也有效,但我想坚持瞄准原始的。net框架2.0。
  • 我的项目没有预预器定义:_HAS_ITERATOR_DEBUGGING = 0。据我所知,在/clr中编译_HAS_ITERATOR_DEBUGGING不再被支持(参见Hans Passat回答中的链接)