سؤال

في الأساس لدي ملف رأس مثل هذا:

#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، وينتاب، WSAAPI) ولكنها تنتهي دائما مع نفس رسالة الخطأ.

هل كانت مفيدة؟

المحلول 2

تم حلها! شكرا لكم جميعا لمساعدتكم. لإصلاحه لقد غيرت Typedef كما يلي:

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

أساسا أنا نسخ ولصق من Winsock2.h: P

نصائح أخرى

مع الأخذ في الاعتبار ردكم على Remus Rusanu، إذا كان السبب في أنك تريد القيام بذلك هو فقط للمنفذ بين المنصات المختلفة، فإن التجريد على مستوى الاستيراد هو الطريقة الخاطئة للقيام بما تريد. على سبيل المثال، فإن رموز الخطأ التي ستعود وظائف مأخذ التوصيل المطلقة على منصات مختلفة، تختلف (ليس فقط في معرف / رقمها، ولكن في المعنى، والتوافر).

لقد قمت بذلك من قبل، وذهبت مع وجود وظائف غلاف قصيرة حول وظائف المقبس المحددة من النظام الأساسي (أو وظائف متعددة عند الضرورة)، والتي ترجمت رسائل الخطأ وما إلى ذلك حتى تكون موحدة WRT على طلبي؛ كان لدي ملف / تنفيذ منفصل لكل منصة. عملت بشكل جيد.

بالنظر إلى تعريف Preprocessor الذي أنت و / أو لا تستخدم، فما هي قيمة "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.


يحرر

عندما أقوم بتشغيل التعليمات البرمجية التالية على جهازي، فإنه لا يتعطل، وإرجاع مكالمة SocketStartuptup 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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top