为什么某些头文件需要在Visual Studio中链接库?

时间:2011-07-26 21:49:43

标签: c++ c visual-studio

我正在使用Visual Studio 2003 .NET构建套接字程序

#include <winsock2.h>头文件,但也注意到我必须在WS2_32.lib中链接以修复未解决的winsock函数错误。

在其他家庭作业项目中,我只是添加了一个头文件并使用了它的功能 - 没有添加相应的库。

这是怎么回事?

某些标准头文件库是否已在Visual Studio中预先链接?

谢谢!

4 个答案:

答案 0 :(得分:7)

套接字函数实际上是在ws2_32.dll中实现的。为了使链接器能够找到它们,您需要将ws2_32.lib 导入库添加到项目中。请注意,导入库不包含函数的实际代码,而只包含有关在何处查找实际函数的信息(在ws2_32.dll中)。

您没有提到您所引用的其他头文件,但如果它类似于<string.h>,那么它已经存在于MSVC运行时库中;如果它类似<windows.h>,则这些函数由导入库提供,例如kernel32.libuser32.libgdi32.lib。这些库可能已包含在您的链接器设置中。

答案 1 :(得分:6)

默认情况下,Visual Studio包含最常用的Win32 .lib文件,例如: kernel32.lib,user32.lib,advapi32.lib等。对于更多深奥的库,您需要自己添加.lib文件。

答案 2 :(得分:2)

默认情况下,Visual Studio将链接到标准库,因此如果要包含标题库,则不需要显式添加库。这适用于stdio.hiostreamstdlib.h之类的内容。

还有一些标题文件,例如标准模板库使用的标题文件(有人会在一分钟内说它实际上只是称为'标准库',但是我读过的大多数书籍,以及微软的docs也引用了STL,例如<vector><list>,它们将所有代码定义为模板,这些模板由编译器扩展为完整函数,因此它们不需要在库中链接。

略微搁置:还有一种自动链接库的机制。只需添加:

#pragma comment(lib, "ws2_32.lib")

代码中的某处。 Boost使用这种技术,以便根据编译器设置链接到库的正确构建。

答案 3 :(得分:2)

这与Visual Studio无关;这就是C / C ++的编译工作原理。

所有标题都是声明或定义符号。函数,变量,typedef,类等

标题可以说:

int SomeFunction();

这是一个功能声明。为了编译使用SomeFunction的代码,您必须声明SomeFunction存在。此声明必须在之前使用它的代码。

这些声明通常在头文件中。

但是,声明也是一种承诺。函数定义是使函数有效的实际C / C ++源代码。声明说,“稍后,你将能够找到这个的定义。”这是您对编译器和链接器的承诺。

除非所有使用的声明都有定义,否则无法成功链接C / C ++代码。其中一些定义来自您自己编译的代码,但其中一些来自外部库。外部库具有头文件,提供C / C ++函数,类型等的声明。但是它们也有库文件(在VC ++中,它们使用.lib扩展名)提供定义这些功能。

如果您使用标头中的声明,而不链接到提供这些符号的定义的库文件,则会出现链接器错误。

请注意,头文件也可以包含定义;很多C ++标准库,而Boost必须完全由头文件定义。所以没有要包含的库。图书馆的文档应该告诉你是否有.lib链接与否。