Pregunta

Básicamente tengo un archivo de cabecera de esta manera:

#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

y luego hago algo como esto:

    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;

Sin embargo, cuando llamo a esta función (la línea con (* Inicio) (prueba, y wsdata)) me sale este mensaje de error:

  

excepción no controlada en 0x7868146a en   SOCKETS.EXE: 0xc0000005: Acceso   violación.

He intentado cambiar la convención de llamada (__cdecl, WINAPI, WSAAPI) pero siempre termina con el mismo mensaje de error.

¿Fue útil?

Solución 2

Resuelto! Gracias por toda tu ayuda. Para solucionarlo acabo de cambiar el typedef de la siguiente manera:

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

Básicamente copio y pegado de Winsock2.h: P

Otros consejos

Teniendo en cuenta su respuesta a Remus Ruşanu, si la razón por la que está queriendo hacer esto es sólo para puerto entre diferentes plataformas, haciendo abstracción a nivel de importación es el camino equivocado para hacer lo que quiera. Por ejemplo, los códigos de error que las funciones de socket de aspecto similar en las diferentes plataformas volverán, variar (no sólo en su ID / número, pero en su significado, y disponibilidad).

He hecho esto antes, y fui con tener funciones de contenedor cortas alrededor de las funciones de socket específicos de la plataforma (o varias funciones cuando sea necesario), que traduce los mensajes de error, etc. así que eran WRT uniforme a mi solicitud; Tenía un archivo / aplicación separada para cada plataforma. Funcionó bien.

Teniendo en cuenta la definición de preprocesador la que se encuentra y / o no está utilizando, ¿cuál es el valor de "WINAPI" cuando se compila? Lo digo porque windef.h contiene cosas extrañas como ...

#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

En las definiciones de typedef, probarlo con el uso de __stdcall en lugar de WINAPI.


Editar

Al ejecutar el siguiente código en mi máquina, que no se desplome, y la llamada socketStartup devuelve 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;
}

Eso es utilizando Visual C ++ 2008, con la siguiente línea de comandos del compilador:

/Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /Gm /EHsc /RTC1 /MDd /Fo"Debug\\" /Fd"Debug\vc90.pdb" /W3 /nologo /c /ZI /TP /errorReport:prompt
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top