问题描述
我正在制作一个使用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#回调之后的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!