使用调用LoadLibrary和GetProcAddress的功能的WinSock
-
18-09-2019 - |
题
基本上我有这样一个头文件:
#if WIN32
typedef DWORD (WSAAPI *SocketStartup) (WORD wVersionRequested, LPWSADATA lpWSAData);
typedef SOCKET (WINAPI *MakeSocket)(IN int af, IN int type, IN int protocol, IN LPWSAPROTOCOL_INFOW lpProtocolInfo, IN GROUP g, IN DWORD dwFlags );
typedef DWORD (WINAPI *SocketSendFunc) (IN SOCKET s,__in_bcount(len) const char FAR * buf, IN int len,IN int flags);
typedef DWORD (WINAPI *GetLastSocketErrorFunc)();
typedef DWORD (WINAPI *ShutdownSocketFunc)(SOCKET hSocket, int how);
typedef DWORD (WINAPI *CloseSocketFunc)(SOCKET hSocket);
#endif
然后我做这样的事情:
SocketStartup* start = (SocketStartup*)GetProcAddress(socketLib,"WSAStartup");
getLastSocketError = (GetLastSocketErrorFunc*)GetProcAddress(socketLib,"WSAGetLastError");
closeSocket = (CloseSocketFunc*)GetProcAddress(socketLib,"closesocket");
shutdownSocket = (ShutdownSocketFunc*) GetProcAddress(socketLib,"shutdown");
socketSend = (SocketSendFunc*) GetProcAddress(socketLib, "send");
if(start == 0 || getLastSocketError == 0 || closeSocket == 0 || shutdownSocket == 0
|| socketSend == 0)
{
printf("[!] Failed to find entry points in Ws2_32.dll. Error Code: %d\n", GetLastError());
CloseLibraries();
ErrorExit();
}
WSADATA wsdata;
//ZeroMemory(&wsdata,sizeof(wsdata));
printf("error: %d\n", GetLastError());
WORD test = MAKEWORD(1,1);
int result = (*start)(test, &wsdata);
return result == 0;
然而,当我调用此函数(带有(*开始)(测试,&wsdata)行)我得到这个错误消息:
在0x7868146a未处理异常 SOCKETS.EXE:0000005:访问 冲突。
我试图改变调用约定(__cdecl,WINAPI,WSAAPI),但它总是与相同的错误消息结束。
解决方案 2
解决!谢谢大家的帮助。为了修正它我只是改变了的typedef如下:
typedef int (WSAAPI SocketStartup)( IN WORD wVersionRequested, OUT LPWSADATA lpWSAData );
基本上我复制并粘贴Winsock2.h:P
其他提示
考虑到到莱姆斯Rusanu您的回复,如果你想这样做的原因只是为了在不同平台之间的端口,在进口层面抽象是错误的方式做你想做的。例如,错误代码在不同平台上外观相似套接字函数将返回,变化(不只是在它们的ID /号码,但在含义,和可用性)。
我这样做过,并用具有围绕特定于平台的socket函数(或多个功能在必要时)短暂的包装功能,即翻译的错误消息等,使他们统一WRT我的应用程序去;我不得不为每个平台单独的文件/执行。它运作良好。
由于预处理器定义,你是和/或不使用,什么是“WINAPI
”当你编译它的价值呢?我这么问是因为windef.h
包含像......奇怪的事情
#ifdef _MAC
#define CALLBACK PASCAL
#define WINAPI CDECL
#define WINAPIV CDECL
#define APIENTRY WINAPI
#define APIPRIVATE CDECL
#ifdef _68K_
#define PASCAL __pascal
#else
#define PASCAL
#endif
#elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
#define CALLBACK __stdcall
#define WINAPI __stdcall
#define WINAPIV __cdecl
#define APIENTRY WINAPI
#define APIPRIVATE __stdcall
#define PASCAL __stdcall
#else
#define CALLBACK
#define WINAPI
#define WINAPIV
#define APIENTRY WINAPI
#define APIPRIVATE
#define PASCAL pascal
#endif
在你的typedef定义,使用替代__stdcall
WINAPI
试试吧。
修改强>
当我跑我的机器下面的代码,它不会崩溃,而socketStartup调用返回0:
#include "windows.h"
typedef DWORD (PASCAL FAR *SocketStartup) (WORD wVersionRequested, LPWSADATA lpWSAData);
int main(int argc, char* argv[])
{
HMODULE hModule = LoadLibrary("wsock32.dll");
SocketStartup socketStartup = (SocketStartup)GetProcAddress(hModule, "WSAStartup");
WSADATA wsdata;
WORD test = MAKEWORD(1,1);
int result = (*socketStartup)(test, &wsdata);
return result == 0;
return 0;
}
这是用Visual C ++ 2008,用下面的编译器命令行:
/Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /Gm /EHsc /RTC1 /MDd /Fo"Debug\\" /Fd"Debug\vc90.pdb" /W3 /nologo /c /ZI /TP /errorReport:prompt
不隶属于 StackOverflow