проблема в прямом объявлении функции closesocket - PullRequest
1 голос
/ 28 октября 2019

У меня есть простой winsock в c ++, и я не хочу включать весь заголовок windows.h или другие заголовки winsock в заголовок оболочки

Это сокращает время компиляции и облегчает работу в идеале. и чтобы уйти от windows.h до проблемы с заголовками winsock

для большинства функций 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
    );

, но я не могу понять, почему он выдает эту ошибку

ОБНОВЛЕНИЕ:

Я устал от clang и получил этипредупреждения

при использовании

__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 и других функций сокета

oneнаходится в заголовке 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, я получаюпервое предупреждение

, а второе предупреждение состоит в том, что я включаю winsock2.h перед windows.h в файл реализации и благодаря этому я получаю второе предупреждение, если в заключение уклоняюсь от первого

Я должен включить свой заголовок перед windows.h или заголовками winsock, чтобы я пришел к проблеме, которую пытался решить (порядок включения)!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...