1

基本的に、次のようなヘッダー ファイルがあります。

#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) の行) を呼び出すと、次のエラー メッセージが表示されます。

sockets.exe の 0x7868146a で未処理の例外: 0xC0000005: アクセス違反。

呼び出し規約 (__cdecl、WINAPI、WSAAPI) を変更しようとしましたが、常に同じエラー メッセージで終了します。

4

3 に答える 3

1

Remus Rusanu への返信を考慮して、これを行いたい理由が異なるプラットフォーム間での移植のみである場合、インポート レベルでの抽象化は、目的を達成するための間違った方法です。たとえば、異なるプラットフォームで同じように見えるソケット関数が返すエラー コードは異なります (ID/番号だけでなく、意味と可用性も異なります)。

私は以前にこれを行ったことがあり、プラットフォーム固有のソケット関数 (または必要に応じて複数の関数) の周りに短いラッパー関数を配置し、エラーメッセージなどを変換して、アプリケーションに対して均一な WRT になるようにしました。プラットフォームごとに個別のファイル/実装がありました。うまくいきました。

于 2009-09-28T00:07:57.497 に答える
0

解決しました!ご協力ありがとうございました。それを修正するために、次のように typedef を変更しました。

typedef int (WSAAPI SocketStartup)(    IN WORD wVersionRequested,    OUT LPWSADATA lpWSAData    );

基本的に、Winsock2.h からコピーして貼り付けました:P

于 2009-09-28T00:18:20.377 に答える
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

__stdcalltypedef 定義では、代わりにを使用して試してください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
于 2009-09-28T00:05:17.410 に答える