本文介绍了“运行时检查失败#0 - ESP的值在功能调用中没有被正确保存”从GameSpy lib的C ++代码成功的C#回调之后的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个使用GameSpy C代码(GP部分)的C#应用​​程序。 C代码成功地调用回调(这是C#代码),但是在回调完成之后,我收到这个错误运行时检查失败#0 - 在函数调用中ESP的值没有正确保存。我从C代码中创建了一个DLL,如下所示:

  
// 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电子邮件[GP_EMAIL_LEN],
const gsi_char密码[GP_PASSWORD_LEN],
GPEnum防火墙,
GPEnum阻止,
GPCallback回调,
void * param
);

C#正在这样调用:

  
不安全的public delegate void GPCallback(
GPConnection * connection,
// GPConnectResponseArg arg,
IntPtr arg,
IntPtr param
);

[DllImport(saketestd.dll)]
不安全的静态外部GPResult gpConnect(
GPConnection *连接,
gsi_char nick,
gsi_char电子邮件,
gsi_char密码,
GPEnum防火墙,
GPEnum阻止,
GPCallback回调,
IntPtr param
);
不安全的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.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;
}

不安全public void ConnectResponse(
GPConnection * connection,
// GPConnectResponseArg arg,
IntPtr argPtr,
IntPtr param
){
debug.AddLine(this.getMethodName()+用连接调用:+(* 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中的调用约定(可能吗?)。任何其他想法?

解决方案

检查您正在使用的呼叫惯例。

  [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 

其他相关问题:


I'm making a C# application which is using GameSpy C code (the GP part). The C code is calling a callback (which is C# code) succesfully, but I get this error "Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call" right after the callback is done. I've made a DLL out of C code, BTW like this:


    // 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# is calling it like this:


   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);
   }
  }

I believe that I need to clear the stack in my callback or change the calling convention in the DLL (is that possible?). Any other ideas?

解决方案

Check the calling conventions you are using.

 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]

Reference to other related question: Callback from C function - crash

这篇关于“运行时检查失败#0 - ESP的值在功能调用中没有被正确保存”从GameSpy lib的C ++代码成功的C#回调之后的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 15:53