Pergunta

Basicamente, eu tenho um arquivo de cabeçalho como este:

#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

e então eu fazer algo parecido com isto:

    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;

No entanto, quando eu chamar esta função (a linha com (* start) (teste, e wsdata)) eu recebo essa mensagem de erro:

Excepção em 0x7868146a em SOCKETS.EXE: 0xC0000005: Acesso violação.

Eu tentei mudar a convenção de chamada (__cdecl, WinAPI, WSAAPI), mas ele sempre termina com a mesma mensagem de erro.

Foi útil?

Solução 2

resolvido! Obrigado a todos por sua ajuda. Para corrigi-lo Eu só mudou o typedef da seguinte forma:

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

Basicamente eu copiar e colado de Winsock2.h: P

Outras dicas

Tendo em conta a sua resposta a Remus Rusanu, se a razão que você está querendo fazer isso é apenas para a porta entre diferentes plataformas, abstraindo ao nível de importação é a maneira errada de fazer o que quiser. Por exemplo, os códigos de erro que as funções de soquete de aparência semelhante em diferentes plataformas vai voltar, variar (e não apenas em seu id / número, mas em significado e disponibilidade).

Eu tenho feito isso antes, e passou a ter funções curtas invólucro em torno do soquete funções plataforma específica (ou várias funções quando necessário), que mensagens de erro traduzido etc, para que eles eram WRT uniforme ao meu pedido; Eu tinha um arquivo / implementação separada para cada plataforma. Funcionou bem.

Dada a definição de pré-processamento que você é e / ou não estiver usando, o que é o valor de "WINAPI" quando você compilá-lo? Estou perguntando porque windef.h contém coisas estranhas 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

Em suas definições typedef, experimentá-lo com o uso de __stdcall vez de WINAPI.


Editar

Quando eu execute o seguinte código na minha máquina, ele não falha, e as chamadas socketStartup retorna 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;
}

Isso é usando o Visual C ++ 2008, com a seguinte linha de comando do 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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top