有一个令我疑惑的链接错误,希望能得到朋友们的帮助。
用 vscode 写的 main.cpp
,手动编译 g++ -o main main.cpp -lwsock32
。
#include <stdlib.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
int main()
{
WSADATA wsa_data;
WSAStartup(MAKEWORD(2, 2), &wsa_data);
WSAEVENT event = WSACreateEvent();
WSACleanup();
return 0;
}
报错如下:
undefined reference to `__imp_WSACreateEvent'
collect2.exe: error: ld returned 1 exit status
这很明显是一个链接错误,但是我已经包含了 winsock2.h
头文件,编译时也指定了链接库 -lwsock32
。
更奇怪的是,WSAStartup
和 WSACleanup
没问题。
这个链接错误是因为你链接的是旧版本的 WinSock 库,而 WSACreateEvent 函数只存在于 WinSock 2.0 或更高版本的库中。可以尝试使用 -lws2_32 链接库,这个库包含了 WinSock 2.0 的所有函数。修改编译指令为 g++ -o main main.cpp -lws2_32,应该可以解决问题。
感谢,亲测有效,另外问问大佬,当我包含一个头文件的时候,我怎么知道链接其动态库的名称是什么呢?
就比如这里include
了winsock2.h
,也知道要通过-l
选项指定对应的动态库,但我怎么知道它的名称是什么呢?有哪些途经可以得知吗?
@zwjason: 在 Windows 平台上,使用头文件时需要链接相应的库文件。对于大多数库,库文件名称和头文件名称是一致的,只是后缀不同。例如,如果你包含了 winsock2.h 头文件,对应的库文件应该是 ws2_32.lib 或 ws2_32.dll。库文件名称可以通过库的文档或者操作系统提供商的文档进行查找。
如果你不知道该头文件对应的库文件的名称,可以尝试通过搜索引擎查询,或者查看操作系统提供商的文档。另外,你可以使用命令行工具 dumpbin 来查看静态库或动态库中包含的导出符号(Export Symbols),来确定该库文件是否包含了你需要的符号。
例如,要查看 ws2_32.dll 中是否包含了 WSACreateEvent 函数,可以在命令行中使用以下命令:
bash
dumpbin /exports ws2_32.dll
这个命令会列出 ws2_32.dll 中包含的导出符号,你可以从中查找到 WSACreateEvent 函数,并确定它在哪个库文件中定义。
undefined reference to `__imp_WSACreateEvent':找不到实现类?
– 快乐的凡人721 1年前@快乐的凡人721: 应该是吧,那应该怎么解决呢。其实是我头铁想用vscode写,我在visual studio下面只需要指定依赖库ws2_32.lib之后,上述代码就可以编译运行了。
– zwjason 1年前