C# DllImport 调用非托管 C++ 函数回调
C# DllImport calling un-managed C++ function callback
您好,我有一个 C# WinForm 应用程序,我可以通过 DllImport 从 libnetclient.dll
调用函数,如下所示:
[DllImport("libnetclient.dll", CharSet = CharSet.Auto)]
public static extern int NETCLIENT_Initialize(int bPriorRGB16 = 0);
然后我可以正常使用以下功能:
int ini = NETCLIENT_Initialize();
memoBox.AppendText("NETCLIENT_Initialize = " + ini.ToString()+Environment.NewLine);//append to box
此回调在登录功能完成后发生。
我的问题是回调函数。
在 C++ netclient.h
头文件中,指针如下所示:
NETCLIENT_API int API_CALL NETCLIENT_RegLoginMsg(void* pUsr, void (CALLBACK * FUNLoginMsgCB)(int nMsg, void * pUsr));
我试着在 C# 中这样调用它:
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;
}
}
但是无论我做什么,结果总是 1。我仔细检查了我的登录详细信息,一切都是正确的。如果有人有任何建议或示例,我们将不胜感激。
过了一会儿我想通了。我使用 IntPtr pUsr
不正确,因为在我的例子中它可能指向任何东西它指向 this
意思是 windows 形式。
此外,所有 DLLs
都必须由 CallingConvention = CallingConvention.StdCall
调用,有些留在 CharSet = CharSet.Auto
.....
现在可以使用了。
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;
}
}
您好,我有一个 C# WinForm 应用程序,我可以通过 DllImport 从 libnetclient.dll
调用函数,如下所示:
[DllImport("libnetclient.dll", CharSet = CharSet.Auto)]
public static extern int NETCLIENT_Initialize(int bPriorRGB16 = 0);
然后我可以正常使用以下功能:
int ini = NETCLIENT_Initialize();
memoBox.AppendText("NETCLIENT_Initialize = " + ini.ToString()+Environment.NewLine);//append to box
此回调在登录功能完成后发生。
我的问题是回调函数。
在 C++ netclient.h
头文件中,指针如下所示:
NETCLIENT_API int API_CALL NETCLIENT_RegLoginMsg(void* pUsr, void (CALLBACK * FUNLoginMsgCB)(int nMsg, void * pUsr));
我试着在 C# 中这样调用它:
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;
}
}
但是无论我做什么,结果总是 1。我仔细检查了我的登录详细信息,一切都是正确的。如果有人有任何建议或示例,我们将不胜感激。
过了一会儿我想通了。我使用 IntPtr pUsr
不正确,因为在我的例子中它可能指向任何东西它指向 this
意思是 windows 形式。
此外,所有 DLLs
都必须由 CallingConvention = CallingConvention.StdCall
调用,有些留在 CharSet = CharSet.Auto
.....
现在可以使用了。
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;
}
}