windows CRT 10.0 版的 LNK2022 和 LNK2034 链接器错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5573897/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
LNK2022 and LNK2034 linker errors with version 10.0 of the CRT
提问by C Johnson
Sorry to bother anyone with this question, but I've been researching this for hours, with no resolution yet:
很抱歉用这个问题打扰任何人,但我已经研究了几个小时,但还没有解决方案:
I am porting a rather massive application to the 10.0 CRT (compiler) in Visual Studio 2010. The app is managed C++/CLI that uses /clr. Most of the code is native (95%), with a few managed portions here and there in it.
我正在将一个相当大的应用程序移植到 Visual Studio 2010 中的 10.0 CRT(编译器)。该应用程序是使用 /clr 的托管 C++/CLI。大多数代码是原生的 (95%),其中有一些托管部分。
So my job is to make the switch in the .vcxproj to target the newer 10.0 CRT (i.e. compiler). We were previously using v90, or using the VC compiler that came with VS 2008 SP1.
所以我的工作是在 .vcxproj 中进行切换,以针对较新的 10.0 CRT(即编译器)。我们之前使用的是 v90,或者使用 VS 2008 SP1 附带的 VC 编译器。
Ok, so breaking changes? Seems like a bunch actually. I fixed a few iterator issues dealing with sets, which all was all pretty easy.
好的,那么重大更改?其实好像是一堆。我修复了一些处理集合的迭代器问题,这一切都非常简单。
But these linker errors are killing me. Any help would be appreciated:
但是这些链接器错误正在杀死我。任何帮助,将不胜感激:
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)
I went ahead and undecorated the symbol:
我继续并未修饰符号:
??0?$allocator@D@std@@$$FQAE@ABV01@@Z
and got:
并得到:
public: __thiscall std::allocator<char>::allocator<char>(class std::allocator<char> const &)
So, as I understand it, the msvcmrtd.lib file has this std::allocator compiled one way, and something else in my project settings (#pragma managed ??) is compiled another, different way. But if so, what do I look for? This has been compiling fine for years using the old compilers.
所以,据我所知,msvcmrtd.lib 文件以一种方式编译了这个 std::allocator,而我的项目设置(#pragma managed ??)中的其他东西以另一种不同的方式编译。但如果是这样,我在寻找什么?使用旧的编译器多年来一直编译得很好。
Note: We currently the 3.5 .NET framework (Not sure if that helps or not... I doubt it)
注意:我们目前使用 3.5 .NET 框架(不确定这是否有帮助...我对此表示怀疑)
Thanks
谢谢
采纳答案by Hans Passant
This is a hard to diagnose problem, the linker errors stink and are poorly documented. There's a post from Stephan Lavavej, the STL maintainer at Microsoft about it in this thread, bottom of the page. I have to say I don't see much of any advice in it, beyond trying to disable iterator debugging in your project settings (_HAS_ITERATOR_DEBUGGING = 0 in the preprocessor definitons).
这是一个难以诊断的问题,链接器错误很糟糕,而且文档也很差。有一篇来自 Microsoft 的 STL 维护者 Stephan Lavavej 的帖子,该帖子位于页面底部的此线程中。我不得不说,除了尝试在项目设置中禁用迭代器调试(预处理器定义中的 _HAS_ITERATOR_DEBUGGING = 0)之外,我没有看到任何建议。
You do need to consider a code review. It sure looks like you are compiling STL code into managed code. That works in general (minus the linker hassle) but it is really the wrong thing to do. Leave the STL collection classes to your native code, use the BCL collection classes (List<> etc) in your managed code.
您确实需要考虑代码。看起来您正在将 STL 代码编译为托管代码。这在一般情况下有效(减去链接器的麻烦),但这确实是错误的做法。将 STL 集合类留给您的本机代码,在您的托管代码中使用 BCL 集合类(List<> 等)。
回答by Paullie
In my case what helped was changing the TargetFramework in the .VCXPROJ to :
在我的情况下,帮助将 .VCXPROJ 中的 TargetFramework 更改为:
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
But as you've mentioned you need to compile against 3.5 I am not sure what you can do in that case.
但是正如您所提到的,您需要针对 3.5 进行编译,我不确定在这种情况下您可以做什么。
回答by kornman00
I recently migrated a VS2008 project to VS2012 that included a C++/cli project and experienced these errors. I'm pretty anal retentive when it comes to my project/build files so I setup some custom .props msbuild files that the projects all import from (to avoid all the repeated and Condition riddled elements in the msbuild XML).
我最近将一个 VS2008 项目迁移到 VS2012,其中包含一个 C++/cli 项目并遇到了这些错误。当涉及到我的项目/构建文件时,我非常坚持不懈,所以我设置了一些自定义的 .props msbuild 文件,这些文件都是从这些文件中导入的(以避免 msbuild XML 中的所有重复和条件混乱的元素)。
So pretend the project was Example.vcxproj. and near the start I had this:
所以假设项目是 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" />
I had my FileWithCommonSettings.props file (where I have -TargetFrameworkVersion- defined) being included -after- Microsoft.Cpp.props. I instead opted to try setting -TargetFrameworkVersion- before Cpp.props, as you can see in the commented out XML. Doing this fixed all the linker issues I was getting. My guess is that Cpp.Default.props defaults to v4.0 in VS2010 and later.
我的 FileWithCommonSettings.props 文件(其中定义了 -TargetFrameworkVersion-)被包含在 -after-Microsoft.Cpp.props 中。我选择尝试在 Cpp.props 之前设置 -TargetFrameworkVersion-,正如您在注释掉的 XML 中看到的那样。这样做解决了我遇到的所有链接器问题。我的猜测是 Cpp.Default.props 在 VS2010 及更高版本中默认为 v4.0。
Hope this helps
希望这可以帮助
edit: Refering to this social.msdn thread, it would appear you need to use VS2010 (ie, toolset v100) in order to actually target v3.5. I didn't realize I was silently targeting 4.0 still with vc110...but it was only after I added that -TargetFrameworkVersion- element did I get rid of the linker errors. After switching to vc100 toolset the linker errors came back.
编辑:参考此 social.msdn 线程,您似乎需要使用 VS2010(即工具集 v100)才能实际针对 v3.5。我没有意识到我仍然使用 vc110 默默地瞄准 4.0……但只有在我添加 -TargetFrameworkVersion- 元素之后,我才摆脱了链接器错误。切换到 vc100 工具集后,链接器错误又回来了。
回答by GloriousLemon
Although my solution to this issue does not address why it happens, I'm noting my observations in case anyone else comes across my same scenario.
虽然我对这个问题的解决方案没有解决它为什么会发生,但我会注意到我的观察,以防其他人遇到我的相同情况。
I too received similar errors compiling my clr project. My goal was to upgrade my version to 11.0, but retain .NET framework 2.0 as the target. In my case, I saw Lnk2034 and lnk2020 errors (different from the lnk2022 noted above).
我在编译我的 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)
...
Initially, I was following Hans Passat's advice by correcting the use of the native containers in this project. I commented out all instances of those containers to verify that they were indeed the cause of failure.
最初,我遵循 Hans Passat 的建议,更正了本项目中原生容器的使用。我注释掉了这些容器的所有实例,以验证它们确实是失败的原因。
During the investigation, I discovered that the following line caused my error:
在调查过程中,我发现以下行导致了我的错误:
std::wstringstream wstream;
wstream << " Failed to to do something \'" << var << "\'.";
The moment I corrected it to the following, those errors went away.
当我将其更正为以下内容时,这些错误就消失了。
std::wstringstream wstream;
wstream << L" Failed to to do something \'" << var << L"\'."; // Added wide string literal.
No idea why such a line would cause this behaviour, but it did.
不知道为什么这样的线会导致这种行为,但确实如此。
Side Note:
边注:
- Targeting a higher .NET framework (4.0) also worked, but I wanted to stick to target the original .NET framework of 2.0.
- My project did not have the preprecossor definition: _HAS_ITERATOR_DEBUGGING = 0. To my understanding, compiling _HAS_ITERATOR_DEBUGGING in /clr is no longer supported (See link in Hans Passat's answer)
- 以更高的 .NET 框架 (4.0) 为目标也有效,但我想坚持以 2.0 的原始 .NET 框架为目标。
- 我的项目没有 preprecossor 定义:_HAS_ITERATOR_DEBUGGING = 0。据我所知,不再支持在 /clr 中编译 _HAS_ITERATOR_DEBUGGING(参见 Hans Passat 回答中的链接)
回答by Atarashii
for anyone like me that this answer did not ring helpful, a second option is to go to: Project Properties->Configuration Properties->General->Project Defaults->.NET Target Framework Versionand set it to v4.0
对于像我这样认为这个答案没有帮助的人,第二个选项是去: 项目属性->配置属性->常规->项目默认值->.NET目标框架版本并将其设置为v4.0
https://connect.microsoft.com/VisualStudio/feedbackdetail/view/806238/unwarranted-linker-errors-using-stl-filestream-class-in-managed-classes-in-c-11-clihas an obscure answer from Microsoft team that fixed my issue.
https://connect.microsoft.com/VisualStudio/feedbackdetail/view/806238/unwarranted-linker-errors-using-stl-filestream-class-in-managed-classes-in-c-11-cli有一个模糊的答案来自微软团队解决了我的问题。