C++ 在库中使用 fstream 时,我在可执行文件中收到链接器错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8528437/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:43:34  来源:igfitidea点击:

When using fstream in a library I get linker errors in the executable

c++visual-c++lnk2019lnk2001

提问by tweetypi

When I add

当我添加

#include <fstream>

and try to use

并尝试使用

std::ifstream (i.e. std::ifstream ifile(pDest))

in my library I get the following linker errors when compiling a project whih uses the library:

在我的库中,编译使用该库的项目时出现以下链接器错误:

Error   2   error LNK2019: unresolved external symbol __CrtDbgReportW referenced in function "public: wchar_t * & __thiscall std::vector<wchar_t *,class std::allocator<wchar_t *> >::operator[](unsigned int)" (??A?$vector@PA_WV?$allocator@PA_W@std@@@std@@QAEAAPA_WI@Z) C:\zipprojnotworking\CPPzip\UI\TestingZipper\Console.lib(ZipLib.obj)  TestingZipper
Error   3   error LNK2001: unresolved external symbol __CrtDbgReportW C:\zipprojnotworking\CPPzip\UI\TestingZipper\libcpmtd.lib(stdthrow.obj) TestingZipper
Error   4   error LNK2019: unresolved external symbol __free_dbg referenced in function "private: void __thiscall std::_Yarn<char>::_Tidy(void)" (?_Tidy@?$_Yarn@D@std@@AAEXXZ) C:\zipprojnotworking\CPPzip\UI\TestingZipper\Console.lib(ZipLib.obj)  TestingZipper
Error   5   error LNK2001: unresolved external symbol __free_dbg    C:\zipprojnotworking\CPPzip\UI\TestingZipper\libcpmtd.lib(xdebug.obj) TestingZipper
Error   6   error LNK2001: unresolved external symbol __free_dbg    C:\zipprojnotworking\CPPzip\UI\TestingZipper\libcpmtd.lib(locale0.obj)    TestingZipper
Error   7   error LNK2019: unresolved external symbol __malloc_dbg referenced in function "void * __cdecl operator new(unsigned int,struct std::_DebugHeapTag_t const &,char *,int)" (??2@YAPAXIABU_DebugHeapTag_t@std@@PADH@Z) C:\zipprojnotworking\CPPzip\UI\TestingZipper\libcpmtd.lib(xdebug.obj) TestingZipper
Error   8   error LNK2001: unresolved external symbol __malloc_dbg  C:\zipprojnotworking\CPPzip\UI\TestingZipper\libcpmtd.lib(locale0.obj)    TestingZipper
Error   9   error LNK2019: unresolved external symbol __calloc_dbg referenced in function __Getctype    C:\zipprojnotworking\CPPzip\UI\TestingZipper\libcpmtd.lib(_tolower.obj)   TestingZipper Error 10  error LNK1120: 4 unresolved externals   C:\zipprojnotworking\CPPzip\UI\Console\Debug\TestingZipper.exe    TestingZipper

Any ideas why?

任何想法为什么?

回答by CristiFati

5+ years later... the problem (and maybe many others) is already solved (and forgotten :) )

5 年后......问题(也许还有许多其他问题)已经解决(并被遗忘了:))

You have 1 libproject that contains the code above: I assume it's in a .c(xx)file and not in a .hfile (included in both projects), and an appproject that makes use of the previous one.
I've thought about what could the configuration that would yield this behavior be (the libproject building fine and the appproject having these unresolved externals) and the only configuration that stands up is: the libproject is not correct. Let me detail:

您有 1 个包含上述代码的lib项目:我假设它在.c(xx)文件中而不是在.h文件中(包括在两个项目中),以及一个使用前一个的应用程序项目。
我已经考虑过会产生这种行为的配置是什么(构建良好的lib项目和具有这些未解析的外部对象应用程序项目),唯一站起来的配置是:lib项目不正确。详细说一下:

  • One missing symbol is CrtDbgReport, that tells me that the lib is built in Debugmode.
  • The fact that the libis building OK, tells me that either:
    1. The libproject is fine, and the error is in the appproject
    2. The libproject is not fine (and the appproject may or may not be fine) but it's a staticlibrary - and in this case the .objfiles are simply "merged" together in the resulting .libfile - it is not linkedso the linker does not search for unresolved externals at this point and it will only search when this library will be linked in an executable (.exeor .dll). This is backed out by the fact that I saw libcpmtd.lib(1)in the error log: using the static runtime library ((U)CRT)version (especially in a project that contains libraries) only makes sense when building a static app(usually designed to run in a stripped outenvironment - e.g. on a "Windows minimalistic core" distribution where it could only need core libraries like: ntdll.dll, kernel32.dll, ...).
  • The fact that there were no duplicate symbols at link time (appproject) rules out the 1st option.
  • 一个缺失的符号是CrtDbgReport,它告诉我该库是在调试模式下构建的。
  • lib正在构建OK的事实告诉我:
    1. LIB项目是好的,错误是在应用项目
    2. LIB项目不精(和应用项目可能会或可能不会被罚款),但它是一个静态库-在这种情况下,.OBJ中所产生的文件是简单的“合并”在一起的.lib文件-它不挂这样链接器此时不会搜索未解析的外部文件,它只会搜索此库何时链接到可执行文件(.exe.dll)中。我在错误日志中看到libcpmtd.lib (1)的事实证明了这一点:使用静态运行时库 ((U)CRT)版本(特别是在包含库的项目中)仅在构建静态应用程序时才有意义(通常设计为在剥离的环境中运行- 例如在“ Windows 简约核心”发行版上,它可能只需要核心库,如:ntdll.dll, kernel32.dll, ...)。
  • 在链接时(应用程序项目)没有重复符号这一事实排除了第一个选项。

This is better that we can simplify the environment required for reproducing the behavior. You can switch Project Properties -> Configuration Properties -> General -> Configuration Typeand change from Static Library (.lib)to Dynamic Library (.dll). Now, at the end it will link and will fail spitting the errors when building the libproject.

这更好地我们可以简化重现行为所需的环境。您可以切换Project Properties -> Configuration Properties -> General -> Configuration Type并从Static Library (.lib)更改为Dynamic Library (.dll)。现在,最后它将链接并且在构建lib项目时将无法吐出错误。

1Check [SO]: Errors when linking to protobuf 3 on MSVC 2013for details about the CRT linking types (check the links as well). Also check [SO]: LNK2005 Error in CLR Windows Formfor more details about what happens when building Cand C++code.

1检查[SO]: Errors whenlinksto protobuf 3 on MSVC 2013有关 CRT 链接类型的详细信息(也检查链接)。另请查看[SO]:CLR Windows 窗体中的 LNK2005 错误,以获取有关构建CC++代码时发生的情况的更多详细信息。

A few words about [MSDN.Blogs]: Debug vs Releasebuilds: when building in Debugmode, some instrumentation code is silently added in your code to facilitate debugging. That's why Debugbuild artifacts (vstheir Releasecounterparts):

关于[MSDN.Blogs] 的几句话:调试与发布构建:在调试模式下构建时,一些检测代码会悄悄地添加到您的代码中以方便调试。这就是为什么调试构建工件(它们的发布版本相比):

  • Have significantly larger size
  • Run slower
  • 有明显更大的尺寸
  • 跑得更慢

The code addition is typically achieved by differences between build steps (simplified version):

代码添加通常通过构建步骤(简化版)之间的差异来实现:

  • Preprocess: the _DEBUGmacro is defined (as opposed to Releasewhere NDEBUGis defined). You can browse standard include files and you'll see lots of preprocessor directives (#ifdefs mostly) on these macros. This phase has a direct impact on compile phase
  • Link: the right libraries (that actually contain that instrumentation code) are chosen
  • 预处理:所述_DEBUG宏被定义(相对于推出其中NDEBUG定义)。您可以浏览标准包含文件,并且您会在这些宏上看到许多预处理器指令(主要是#ifdef)。这个阶段对编译阶段有直接影响
  • 链接:选择了正确的库(实际上包含该检测代码)

The most important thing is that the compile (and indirectly, preprocess) and link phases must be in sync. This is not the case for your libproject, so you have an UCRTmismatch (as the 3rd comment states). To fix this, either:

最重要的是编译(以及间接的预处理)和链接阶段必须同步。您的lib项目不是这种情况,因此您的UCRT不匹配(如第三条评论所述)。要解决此问题,请执行以下任一操作

  • Change the _DEBUG/ NDEBUGmacro definition from: Project Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions
  • Change UCRTtype from: Project Properties -> C/C++ -> Code Generation -> Runtime Library
  • _DEBUG/ NDEBUG宏定义更改为:Project Properties -> C/C++ -> Preprocessor -> Preprocessor Definitions
  • 更改UCRT类型:项目属性 -> C/C++ -> 代码生成 -> 运行时库

I listed them both, since I don't know which one is incorrect (as you would want the configuration settings to match the configuration name (Debug/ Release)), but I have a feeling that it's the latter.

我列出了它们,因为我不知道哪个不正确(因为您希望配置设置与配置名称(Debug/ Release)相匹配),但我有一种感觉是后者。

Also, make sure to have consistent settings across projects that are supposed to work together.

此外,请确保在应该协同工作的项目之间具有一致的设置。

回答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有一个模糊的答案来自微软团队解决了我的问题。

I also added this answer to another version of the same problem.

我还将此答案添加到同一问题的另一个版本中。