[英]C++ unmanaged function callback char to C# char
我有一個 C# 表單。 我正在從 C++ dll 調用非托管函數。
我有一個名為FUNDownDevCBEx
的回調,它返回變量int nType, IntPtr pData
。
所以指向struct _tagGPSMDVRInfo p = (_tagGPSMDVRInfo)Marshal.PtrToStructure(pData, typeof(_tagGPSMDVRInfo));
我可以得到指針變量。
但是,當我指向szIDNO
我只得到字符串的最后一個字符,我不知道為什么..
我希望szIDNO
以增量方式顯示名稱,但我只得到最后一個字符。
預期的:
00091
00001
01211
01222
01504
我得到了什么:
4
2
1
1
1
void FUNDownDevCBEx(int nType, IntPtr pData, Form1 form1)
是返回szIDNO
的回調循環
任何建議將不勝感激。
C++ 類型定義:
typedef struct _tagGPSInfo
{
int nID;
char szIDNO[32];
char szName[32];
char szSIMCard[16];
union
{
GPSInfo_S gDVRInfo;
GPSMobileInfo_S gMobileInfo;
GPSDVSInfo_S DVSInfo;
};
}GPSInfo_S, *LPGPSInfo_S;
C++ 回調看起來像這樣:
void (CALLBACK * FUNDownDevCBEx)(int nType, void* pData, void * pUsr)
我的 C# 轉換代碼:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct _tagGPSInfo
{
[MarshalAs(UnmanagedType.I4)]
public int nID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string szIDNO;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string szName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
public string szSIMCard;
}
private void devlist_Click(object sender, EventArgs e)
{
try
{
IntPtr _lHandle = IntPtr.Zero;
NETClass.NETCLIENT_DEVOpenDevDownEx(ref _lHandle);
NETClass.NETCLIENT_DEVSetCharEx( _lHandle);
FUNDownDevCBEx _1callback = new FUNDownDevCBEx(FUNDownDevCBEx);
NETClass.NETCLIENT_DEVRegDevDownCBEx( _lHandle, this, _1callback);
NETClass.NETCLIENT_DEVStartDevDownEx(_lHandle, 0,0);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "List Exception");
return;
}
}
static void FUNDownDevCBEx(int nType, IntPtr pData, Form1 form1)
{
try
{
_tagGPSInfo p = (_tagGPSMDVRInfo)Marshal.PtrToStructure(pData, typeof(_tagGPSInfo));
int nID = p.nID;
string szIDNO = p.szIDNO;
switch (nType)
{
case 0:
form1.Invoke((MethodInvoker)(() => form1.memoBox.AppendText(" DATA =" + pData + " nID=" + nID + " szIDNO=" + szIDNO + Environment.NewLine)));
break;
case 1:
//MessageBox.Show("GPS_DEV_DOWN_GROUP" + Environment.NewLine + " DATA =" + pData + " nID=" + nID);
break;
case 2:
//MessageBox.Show("GPS_DEV_DOWN_FAILED" + Environment.NewLine + " DATA =" + pData );
break;
case 3:
//MessageBox.Show("GPS_DEV_DOWN_SUC" + Environment.NewLine + " DATA =" + pData);
break;
case 4:
//MessageBox.Show("GPS_DEV_DOWN_RELATION" + Environment.NewLine + " DATA =" + pData + " nID=" + nID);
break;
default:
//MessageBox.Show("DEFAULT");
break;
}
//MessageBox.Show("nType= " + nType + " pData= " + pData);
NETClass.NETCLIENT_DEVStopDevDownEx(IntPtr.Zero);
NETClass.NETCLIENT_DEVCloseDevDownEx(IntPtr.Zero);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "FUNDownDevCBEx Exception");
return;
}
}
我的 C# NETClass:
namespace ConversionTest
{
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void FUNDownDevCBEx(int nType, IntPtr data, Form1 form1);
class NETClass
{
[DllImport("libnetclient.dll", CallingConvention = CallingConvention.StdCall,SetLastError = true)]
public static extern int NETCLIENT_DEVOpenDevDownEx(ref IntPtr lpHandle);
[DllImport("libnetclient.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int NETCLIENT_DEVRegDevDownCBEx( IntPtr lHandle, Form1 form1, FUNDownDevCBEx _callback);
[DllImport("libnetclient.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int NETCLIENT_DEVStartDevDownEx( IntPtr lHandle, int nMgrType, int nDevType);
[DllImport("libnetclient.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int NETCLIENT_DEVStopDevDownEx( IntPtr lHandle);
[DllImport("libnetclient.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int NETCLIENT_DEVCloseDevDownEx( IntPtr lHandle);
[DllImport("libnetclient.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int NETCLIENT_DEVSetCharEx( IntPtr lHandle, bool bUtf8 = true);
}
}
感謝您的評論。 解決辦法是晚上好好休息,早上喝杯咖啡。
由於[StructLayout(LayoutKind.Sequential)]
是順序的,結構中的每個變量都必須是順序的。 由於我的原始結構非常長,我在szIDNO
之前錯過了一個int
變量,這導致指針指向我的字符串中的""miss""
4 個字符...
這就是我的理解,可以隨意發表評論......
[StructLayout(LayoutKind.Sequential)]
public struct _tagGPSMDVRInfo
{
//struct now in proper sequence
[MarshalAs(UnmanagedType.I4)]
public int nID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string szName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string szIDNO;// <--- Now in correct position....
[MarshalAs(UnmanagedType.I4)]
public int nJingDu;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 7)]
public string strReserve;
}
static void FUNDownDevCBEx(int nType, IntPtr pData, Form1 form1)
{
try
{
switch (nType)
{
case 0:
_tagGPSMDVRInfo p = new _tagGPSMDVRInfo(); // Create the managed struct
p = Marshal.PtrToStructure<_tagGPSMDVRInfo>(pData);//simplify
int nID = p.nID;
string szIDNO = p.szIDNO;
form1.Invoke((MethodInvoker)(() => form1.textBox4.AppendText(" DATA =" + pData + " nID=" + nID + " szIDNO=" + szIDNO + Environment.NewLine)));
;
break;
case 1:
//MessageBox.Show("GPS_DEV_DOWN_GROUP" + Environment.NewLine + " DATA =" + pData + " nID=" + nID);
break;
case 2:
//MessageBox.Show("GPS_DEV_DOWN_FAILED" + Environment.NewLine + " DATA =" + pData );
break;
case 3:
//MessageBox.Show("GPS_DEV_DOWN_SUC" + Environment.NewLine + " DATA =" + pData);
break;
case 4:
//MessageBox.Show("GPS_DEV_DOWN_RELATION" + Environment.NewLine + " DATA =" + pData + " nID=" + nID);
break;
default:
//MessageBox.Show("DEFAULT");
break;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "FUNDownDevCBEx Exception");
return;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.