Question

En fait, j'ai un fichier d'en-tête comme ceci:

#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

et puis je fais quelque chose comme ceci:

    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;

Cependant, quand je l'appelle cette fonction (la ligne avec (* début) (test, et WSData)) Je reçois ce message d'erreur:

  

exception non gérée à 0x7868146a dans   SOCKETS.EXE: 0xC0000005: Accès   violation.

J'ai essayé de changer la convention d'appel (__cdecl, WINAPI, WSAAPI), mais il finit toujours avec le même message d'erreur.

Était-ce utile?

La solution 2

Résolu! Merci à tous pour votre aide. Pour résoudre ce problème, je viens de changer le typedef comme suit:

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

En fait, je dupliquées d'Winsock2.h: P

Autres conseils

Compte tenu de votre réponse à Remus Rusanu, si la raison pour laquelle vous êtes désireux de le faire est que le port entre les différentes plates-formes, abstraire au niveau des importations est la mauvaise façon de faire ce que vous voulez. Par exemple, les codes d'erreur que les fonctions socket recherche similaires sur différentes plates-formes renverront, varient (et pas seulement dans leur identifiant / numéro, mais dans le sens et la disponibilité).

Je l'ai déjà fait, et je suis allé avec des fonctions ayant court wrapper autour des fonctions de socket spécifiques de la plate-forme (ou plusieurs fonctions si nécessaire), qui traduit les messages d'erreur, etc., afin qu'ils étaient uniformes à ma WRT demande; J'ai eu un fichier / mise en œuvre pour chaque plate-forme. Il a bien fonctionné.

Compte tenu de la définition de préprocesseur que vous êtes et / ou n'utilisez pas, quelle est la valeur de « WINAPI » lors de la compilation? Je demande parce que windef.h contient des choses bizarres comme ...

#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

Dans vos définitions typedef, essayez avec l'aide __stdcall au lieu de WINAPI.


Modifier

Quand je lance le code suivant sur ma machine, il ne tombe pas en panne, et les retours d'appel 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;
}

C'est en utilisant Visual C ++ 2008, avec la ligne de commande du compilateur suivant:

/Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /Gm /EHsc /RTC1 /MDd /Fo"Debug\\" /Fd"Debug\vc90.pdb" /W3 /nologo /c /ZI /TP /errorReport:prompt
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top