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:0xc0000005で:アクセス 違反ます。
私は、呼び出し規約(__cdecl、WINAPI、WSAAPI)を変更しようとしたが、それは常に同じエラーメッセージを表示して終了します。
解決 2
解決!あなたの助けありがとうございました。次のようにそれを修正するために、私はただのtypedefを変更します:
typedef int (WSAAPI SocketStartup)( IN WORD wVersionRequested, OUT LPWSADATA lpWSAData );
基本的に私はコピーしてWinsock2.hから貼り付け:P
他のヒント
のアカウントにレムスRusanuへのお返事を取ると、あなたがこれをやりたいと思っている理由は、唯一の輸入・レベルで抽象化し、異なるプラットフォーム間でのポートにある場合、あなたが欲しいものを行うには間違った方法です。例えば、異なるプラットフォーム上で同様の見ているソケット関数は(だけでなく、そのID /番号ではなく、意味で、および可用性)変わり、エラーコードを返すこと。
私は前にこれをやった、とプラットフォーム固有のソケット関数(または複数の機能に必要な)の周りに短いラッパー関数を持って行き、彼らは私のアプリケーションへの均一な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