Visual Studio LNK1104 而不是 LNK2019

Visual Studio LNK1104 instead of LNK2019

我不明白 Visual Studio(我是 2015 年)如何从头文件中检测到 .lib 文件名。

示例 1
我使用 boost/asio 编写了一个简单的程序来通过 HTTP 请求进行连接。源文件在其顶部包含 <boost/asio.hpp>。我还配置 C/C++ / General / Additional Include Directories 指向 boost 的文件夹。
之后,我构建解决方案并遇到错误:

Error LNK1104 cannot open file 'libboost_system-vc140-mt-gd-1_61.lib'

但我不知道 Visual Studio 从哪里找到 libboost_system-vc140-mt-gd-1_61.lib 这个名字。
- 在 Linker / Input / Additional Dependencies / Edit... 中查找评估值和继承值,没有名为 libboost_system-vc140-mt-gd-1_61.lib
的项目 - 我认为在 <boost/asio.hpp> 中它以某种方式向编译器设置了一些信息:"If you need lib file, look for libboost_system-vc140-mt-gd-1_61.lib, it is the implementation of mine",但我在 boost 文件夹中搜索,没有包含 "libboost_system-vc140-mt-gd-1_61.lib"
的源文件


通常,如果在头文件中声明了一些函数,并且 Visual Studio 不能归档它的实现,那么 LNK2019: unresolved external symbol ... 将被抛出。
然后如果它的实现在 abcxyz.lib 文件中,用户转到 Linker / Input / Additional Dependencies 并添加 abcxyz.lib 没有 指定文件夹包含Linker / General / Additional Libary Directories 中的 .lib 文件。在这种情况下,Error LNK1104 cannot open file 'abcxyz.lib' 将被抛出

那么,为什么上面的例子遇到的是LNK1104错误,而不是LNK2019错误呢?

示例 2
我正在为一个使用 OpenCV 2.4.10 库的项目工作。在分发中,他们给了我带有源代码的项目,但没有将库附加给我。
然后,我下载最新的 OpenCV 2.4.13 并为项目设置,例如附加包含文件夹、附加库文件夹、附加依赖项 (opencv_core2413.lib)。
一切看起来都很好,但是当我构建项目时,它给了我错误:

Error LNK1104 cannot open file 'opencv_core2410d.lib'

我查看了 Linker \ Input \ Additional Dependencies 的评估值(包含 opencv_core2413.lib)和继承值,但没有名为 'opencv_core2410d.lib' 的项目。
尝试查看项目应用的另一个共享 属性 Sheet,但没有名为 'opencv_core2410d.lib'
的条目项 我想删除这个条目,但找不到它在哪里

那么,这里发生了什么?任何人都可以为我解释一下吗?谢谢

LNK1104 让您知道您需要在 Library Directories.

中设置库位置

boost::asio 取决于 boost::system 的错误消息。 boost::system 不是 一个 header-only 库。

您需要将 boost 库的位置添加到解决方案 属性 页面上 VC++ Directories 下的 Library Directories

如果您还没有构建 boost 库,请阅读如何构建的文章 here or you can download it from here

OpenCV 库的位置添加到解决方案的 属性 页面应该可以解决 Example 2.

使用 visual studio,您可以使用

将库请求注入 .obj 文件
#pragma comment( lib, "libname.lib" )

这会导致 linker 在库路径中查找 libname,并确保使用正确的库。

这可以在 link 上使用 /nodefaultlib 来禁用。

对于 windows,类 的实现在发布和调试之间发生了变化(额外的跟踪成员被添加到调试中的结构中)。

根据是否调用 DllMain,实现整理和 CRT 启动的机制不同。

最近 visual studio 也有

#pragma detect_mismatch( "name", "value")

它在每个目标文件中声明其值为 "value"。这确保如果结构在版本或编译选项之间发生变化,它们将变得彼此不兼容。