我在C ++中有一个简单的winsock,并且我不想在包装程序头中包含整个windows.h标头或其他winsock标头
这是为了减少编译时间,并且在思想上很轻巧,并且在出现winsock标头问题之前避开了windows.h
对于大多数winsock函数,只能在cpp实现文件中使用它们,而让我的包装程序简化事情,这是很困难的事情
但是我只需要在头文件中使用closesocket函数,以便在套接字的raii句柄中使用它
using socket_t = uintptr_t;
using SocketHandle = std::unique_ptr<void, ZeroOrMinusHandleDeleter<socket_t, static_cast<socket_t>(-1), false, socket_t, closesocket>>;
我可以使用代理功能,并在cpp文件中实现它,如下所示:
// in .h file
using socket_t = uintptr_t;
int CloseSocket(socket_t fd);
using SocketHandle = std::unique_ptr<void, ZeroOrMinusHandleDeleter<socket_t, static_cast<socket_t>(-1), false, socket_t, CloseSocket>>;
// in .cpp file
int CloseSocket(socket_t fd) { return closesocket(fd); }
但是我不想添加仅重定向到另一个调用的额外函数调用
所以我试图转发这样声明:
extern "C"
{
using socket_t = uintptr_t;
__declspec(dllimport) int __stdcall closesocket(socket_t s);
}
但是我得到了错误:C2375'closesocket':重新定义;不同的链接
我尝试消除__declspec(dllimport)并进行编译,但出现此警告:
C4273'closesocket':DLL链接不一致
我看到上一个与WinSock2.h中的定义相同:
WINSOCK_API_LINKAGE
int
WSAAPI
closesocket(
_In_ SOCKET s
);
但我不明白为什么会产生此错误
更新:
我厌倦了叮当声,并得到了这些警告
使用
时__declspec(dllimport) int __stdcall closesocket(socket_t s);
我知道了
warning : redeclaration of 'closesocket' should not add 'dllimport' attribute [-Wdll-attribute-on-redeclaration]
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um\winsock.h(749): note: previous declaration is here
以及使用
时int __stdcall closesocket(socket_t s);
我明白了
warning : 'closesocket' redeclared without 'dllimport' attribute: previous 'dllimport' ignored [-Winconsistent-dllimport]
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um\winsock2.h(1668): note: previous declaration is here
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um\winsock2.h(1665): note: previous attribute is here
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um\winsock2.h(94): note: expanded from macro 'WINSOCK_API_LINKAGE'
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um\winnt.h(184): note: expanded from macro 'DECLSPEC_IMPORT'
因此,警告我不要在函数声明中添加或删除dllimport真是太神奇了!
从警告中我发现closesocket和其他套接字函数有两个声明
一个在winsock.h标头中,它引起第一个警告:
int PASCAL FAR closesocket ( IN SOCKET s);
和另一个在winsock2.h中的第二个警告:
#if INCL_WINSOCK_API_PROTOTYPES
WINSOCK_API_LINKAGE
int
WSAAPI
closesocket(
_In_ SOCKET s
);
#endif /* INCL_WINSOCK_API_PROTOTYPES */
似乎Windows.h包含winsock.h,因此当我的标头包含在windows.h之后时,我会收到第一个警告
第二个警告是因为我在实现文件中的windows.h之前包含了winsock2.h,因此,如果我逃避了第一个警告,则会得到第二个警告
最后,我必须在Windows.h或Winsock标头之前包含标头,所以我遇到了我要解决的问题(包含顺序)!