问题
Hi I have a C# WinForm app, I am able to call functions from the libnetclient.dll
via DllImport like below:
[DllImport("libnetclient.dll", CharSet = CharSet.Auto)]
public static extern int NETCLIENT_Initialize(int bPriorRGB16 = 0);
I am then able to use the functions as normal such as below:
int ini = NETCLIENT_Initialize();
memoBox.AppendText("NETCLIENT_Initialize = " + ini.ToString()+Environment.NewLine);//append to box
This callback occurs once the login function has completed.
My problem is with a callback function.
Inside the C++ netclient.h
header file the pointer looks like this below:
NETCLIENT_API int API_CALL NETCLIENT_RegLoginMsg(void* pUsr, void (CALLBACK * FUNLoginMsgCB)(int nMsg, void * pUsr));
I tried to call this in C# like such:
public delegate void FUNLoginMsgCB(int nMsg, IntPtr pUsr);
....
....
[DllImport("libnetclient.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int NETCLIENT_RegLoginMsg(IntPtr pUsr, FUNLoginMsgCB _callback);
private void loginbutton_Click(object sender, EventArgs e)
{
var _callback = new FUNLoginMsgCB(DoLoginMsgCB);
NETCLIENT_RegLoginMsg(this.Handle, _callback);//call the callback function
}
private static void DoLoginMsgCB(int nMsg, IntPtr pUsr)
{
switch (nMsg)//switch shows result after login function called
{
case 0:
MessageBox.Show("LOGIN_SUC");
break;
case 1:
MessageBox.Show("LOGIN_FAILED");
break;
case 2:
MessageBox.Show("LOGIN_DISCNT");
break;
case 3:
MessageBox.Show("LOGIN_NAME_ERR");
break;
default:
MessageBox.Show("DEFAULT");
break;
}
}
However no matter what I do the result is always 1. I have double checked my login details and all are correct. If anyone has any advice or examples it'll be greatly appreciated.
回答1:
After a while I figured it out. I was using IntPtr pUsr
incorrectly since it could be pointing to anything in my case it was pointing to this
meaning the windows form.
Also all DLLs
had to be called by CallingConvention = CallingConvention.StdCall
some were left on CharSet = CharSet.Auto
.....
This now works.
public delegate void FUNLoginMsgCB(int nMsg, Form1 form1);
....
....
[DllImport("libnetclient.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int NETCLIENT_RegLoginMsg(Form1 form1, FUNLoginMsgCB _callback);
private void loginbutton_Click(object sender, EventArgs e)
{
var _callback = new FUNLoginMsgCB(DoLoginMsgCB);
NETCLIENT_RegLoginMsg(this, _callback);//call the callback function
}
private static void DoLoginMsgCB(int nMsg, Form1 form1)
{
switch (nMsg)//switch shows result after login function called
{
case 0:
MessageBox.Show("LOGIN_SUC");
break;
case 1:
MessageBox.Show("LOGIN_FAILED");
break;
case 2:
MessageBox.Show("LOGIN_DISCNT");
break;
case 3:
MessageBox.Show("LOGIN_NAME_ERR");
break;
default:
MessageBox.Show("DEFAULT");
break;
}
}
来源:https://stackoverflow.com/questions/59504565/c-sharp-dllimport-calling-un-managed-c-function-callback