【发布时间】:2019-12-27 18:15:24
【问题描述】:
您好,我有一个 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。我已经仔细检查了我的登录详细信息,一切都是正确的。如果有人有任何建议或示例,将不胜感激。
【问题讨论】:
-
您是否尝试过使用
[UnmanagedFunctionPointer(CallingConvention.StdCall)]属性装饰回调的C# 声明? -
是的,我这样称呼它
[DllImport("libnetclient.dll", CallingConvention = CallingConvention.StdCall)] -
对不起,我说的是
FUNLoginMsgCB委托声明 -
感谢您的评论,它的行为似乎相同,没有变化。
-
@PavelAnikhouski 我想我错误地调用了
IntPtr pUsr,也许我不明白。在 C# 中,IntPtr pUsr等同于void* pUsr,但在我的情况下,它应该是this,表示形式...
标签: c# c++ function pointers dllimport