2009-09-23 5 views
0

GameSpy C 코드를 사용하는 C# 응용 프로그램을 만들고 있습니다 (GP 파트). C 코드가 C# 코드 인 콜백을 성공적으로 호출하고 있지만 콜백이 수행 된 직후에이 오류가 발생합니다. Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call 나는이 같은 C 코드에서 DLL을했습니다 :C++ 코드에서 성공적인 C# 콜백 후 "런타임 확인 실패 # 0 - ESP 값이 제대로 저장되지 않았습니다."


    // GPCallback 
    ///////////// 
    __declspec(dllexport) typedef void (* GPCallback)(
     GPConnection * connection, 
     void * arg, 
     void * param 
    ); 

    // gpConnect 
    //////////// 
    __declspec(dllexport) GPResult gpConnect 
    (
     GPConnection * connection, 
     const gsi_char nick[GP_NICK_LEN], 
     const gsi_char email[GP_EMAIL_LEN], 
     const gsi_char password[GP_PASSWORD_LEN], 
     GPEnum firewall, 
     GPEnum blocking, 
     GPCallback callback, 
     void * param 
    ); 

C#을이처럼 호출 :


    unsafe public delegate void GPCallback(
    GPConnection * connection, 
    //GPConnectResponseArg arg, 
    IntPtr arg, 
    IntPtr param 
); 

    [DllImport("saketestd.dll")] 
    unsafe static extern GPResult gpConnect(
    GPConnection * connection, 
    gsi_char nick, 
    gsi_char email, 
    gsi_char password, 
    GPEnum firewall, 
    GPEnum blocking, 
    GPCallback callback, 
    IntPtr param 
); 
    unsafe public bool gpConnectE() { 
    bool ret = false; 
    try { 
    GPResult res; 
    debug.AddLine(this.getMethodName() + ": " + "connection before connect: " + connection.ToString("x")); 
    fixed (int* pconn = &connection) { 
    res = gpConnect(
     pconn, 
     this.NICK, 
     this.EMAIL, 
     this.PASSWORD, 
     GPEnum.GP_NO_FIREWALL, 
     GPEnum.GP_BLOCKING, 
     new GPCallback(this.ConnectResponse), 
     IntPtr.Zero 
    ); 
    } 
    debug.AddLine(this.getMethodName() + ": " + "connection after connect: " + connection.ToString("x")); 
    if (res != GPResult.GP_NO_ERROR) { 
    debug.AddLine(this.getMethodName() + ": " + "failed: " + res); 
    } else { 
    debug.AddLine(this.getMethodName() + ": " + "OK"); 
    ret = true; 
    } 
    } catch (Exception ex) { 
    debug.Text += ex.ToString(); 
    } 
    return ret; 
    } 

    unsafe public void ConnectResponse(
    GPConnection * connection, 
    //GPConnectResponseArg arg, 
    IntPtr argPtr, 
    IntPtr param 
) { 
    debug.AddLine(this.getMethodName() + " called with connection: " + (*connection).ToString("x")); 
    GPConnectResponseArg arg; 
    arg = (GPConnectResponseArg)Marshal.PtrToStructure(argPtr, typeof(GPConnectResponseArg)); 
    if (arg.result == GPResult.GP_NO_ERROR) { 
    debug.AddLine(this.getMethodName() + ": Connected to GP"); 
    this.profileid = arg.profile; 
    } else { 
    debug.AddLine(this.getMethodName() + ": failed"); 
    debug.AddLine(this.getMethodName() + ": result: " + arg.result); 
    debug.AddLine(this.getMethodName() + ": profile: " + arg.profile); 
    debug.AddLine(this.getMethodName() + ": uniquenick: " + arg.uniquenick); 
    } 
    } 

내가 내 콜백에서 스택을 취소하거나 변경할 필요가 있다고 생각 DLL에서 호출 규칙 (그것은 가능합니까?). 다른 아이디어?

답변

3

문제가 예기치 않게 해결 내 자신 (5 시간 인터넷 검색 후). 잘못된 호출 규칙이 이미 의심 스럽지만 올바르게 전환하는 방법을 알지 못했습니다. 여기에 제안 된대로 C 코드에서 변경했습니다 (http://computerarts.com.cn/dotnet-tech/1691/) :