基本上我有一个像这样的头文件:
#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;
但是,当我调用此函数时(带有(* start)(test,& wsdata)的行)我收到此错误消息:
0x7868146a处的未处理异常 sockets.exe:0xC0000005:访问 冲突。
我尝试更改调用约定(__cdecl,WINAPI,WSAAPI),但它始终以相同的错误消息结束。
答案 0 :(得分:1)
考虑到你对Remus Rusanu的回复,如果您想要这样做的原因只是为了在不同平台之间移植,那么在导入级别抽象是做错的方式。例如,类似外观的套接字在不同平台上运行的错误代码将会返回(不仅仅是它们的id / number,而是意义和可用性)。
我以前做过这个,并且在平台特定的套接字函数(或必要的多个函数)周围使用短包装函数,转换错误消息等,以便它们对我的应用程序是统一的WRT;我为每个平台都有一个单独的文件/实现。它运作良好。
答案 1 :(得分:0)
鉴于您正在和/或未使用的预处理器定义,编译时“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
答案 2 :(得分:0)
解决!感谢大家的帮助。为了解决这个问题,我刚刚更改了typedef,如下所示:
typedef int (WSAAPI SocketStartup)( IN WORD wVersionRequested, OUT LPWSADATA lpWSAData );
基本上我从Winsock2.h复制并粘贴:P