我真的必须 link Ws2_32.lib 吗?
Do I actually have to link Ws2_32.lib?
MSDN 上的所有 Winsock2 示例表明我必须静态 link Winsock2 库作为:
#pragma comment(lib, "ws2_32.lib")
Ensure that the build environment links to the Winsock Library file ?>Ws2_32.lib. Applications that use Winsock must be linked with the Ws2_32.lib >library file. The #pragma comment indicates to the linker that the Ws2_32.lib >file is needed.
但为什么我使用它而不是简单地加载 Windows Ws2_32.dll 中的现有内容(据我所知,根据 MSDN https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-recv 的要求,自 Windows 2003 年起)
所以我可以使用这样的东西:
typedef int WSAAPI(WINAPI* recv_func)(SOCKET s, char *buf, int len, int flags);
HINSTANCE hGetProcIDDLL = LoadLibraryA("ws2_32.dll");
my_recv = (recv_func)GetProcAddress(hGetProcIDDLL, "recv");
或者我可以只使用 winsock2.h header 并使用 /MD 标志编译程序:
include <winsock2.h>
//#pragma comment(lib, "ws2_32.lib")
可能吗?我可以像第一个示例那样使用 /MD 或动态加载 ws2_32.dll 而无需将 linking ws2_32.lib 静态地 ws2_32.lib 到我的应用程序,因为自 Win2003 以来所有 Windows 都具有 ws2_32.dll System32 文件夹?
库 ws2_32.lib
是导入库。它由小存根组成,这些存根将重定向到 ws2_32.dll 中的实际实现。 DLL 将在程序加载时加载。它被称为Load-Time Dynamic Linking。
您可以通过比较两个文件的大小来验证这一点。另外你可以使用 dumpbin -symbols ws2_32.lib
。它向您展示了 none 您可能期望从 ws2.h 原型获得的功能。
好吧,您已经在加载时动态加载了 DLL。也可以在 运行 时间使用 LoadLibrary
和 GetProcAddress
执行此操作。但这很麻烦,不会给你带来任何好处。
编辑:
您还 link 其他导入库,但未明确指定。该项目继承自 属性 工作表(请参阅
menu: View -> Other Windows -> Property Manager
) 以及内置规则。您可以在项目属性中看到生成的 linker 命令行。 Select 项目并按 alt-Enter 打开项目属性,然后导航到 Configuration Properties -> Linker -> Input
以显示 linker 命令行。对于 VS2017 Win32 C++ 项目,您可以找到这些导入库:
"kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib"
"advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib"
"odbccp32.lib"
MSDN 上的所有 Winsock2 示例表明我必须静态 link Winsock2 库作为:
#pragma comment(lib, "ws2_32.lib")
Ensure that the build environment links to the Winsock Library file ?>Ws2_32.lib. Applications that use Winsock must be linked with the Ws2_32.lib >library file. The #pragma comment indicates to the linker that the Ws2_32.lib >file is needed.
但为什么我使用它而不是简单地加载 Windows Ws2_32.dll 中的现有内容(据我所知,根据 MSDN https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-recv 的要求,自 Windows 2003 年起)
所以我可以使用这样的东西:
typedef int WSAAPI(WINAPI* recv_func)(SOCKET s, char *buf, int len, int flags);
HINSTANCE hGetProcIDDLL = LoadLibraryA("ws2_32.dll");
my_recv = (recv_func)GetProcAddress(hGetProcIDDLL, "recv");
或者我可以只使用 winsock2.h header 并使用 /MD 标志编译程序:
include <winsock2.h>
//#pragma comment(lib, "ws2_32.lib")
可能吗?我可以像第一个示例那样使用 /MD 或动态加载 ws2_32.dll 而无需将 linking ws2_32.lib 静态地 ws2_32.lib 到我的应用程序,因为自 Win2003 以来所有 Windows 都具有 ws2_32.dll System32 文件夹?
库 ws2_32.lib
是导入库。它由小存根组成,这些存根将重定向到 ws2_32.dll 中的实际实现。 DLL 将在程序加载时加载。它被称为Load-Time Dynamic Linking。
您可以通过比较两个文件的大小来验证这一点。另外你可以使用 dumpbin -symbols ws2_32.lib
。它向您展示了 none 您可能期望从 ws2.h 原型获得的功能。
好吧,您已经在加载时动态加载了 DLL。也可以在 运行 时间使用 LoadLibrary
和 GetProcAddress
执行此操作。但这很麻烦,不会给你带来任何好处。
编辑:
您还 link 其他导入库,但未明确指定。该项目继承自 属性 工作表(请参阅
menu: View -> Other Windows -> Property Manager
) 以及内置规则。您可以在项目属性中看到生成的 linker 命令行。 Select 项目并按 alt-Enter 打开项目属性,然后导航到 Configuration Properties -> Linker -> Input
以显示 linker 命令行。对于 VS2017 Win32 C++ 项目,您可以找到这些导入库:
"kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib"