C#调用C++DLL 获取的结构体里 char[] 乱码
2019年的4月23号 今天天气 没有了前几天的惠风和畅 但仍是天朗气清
来邦对讲SDK二次开发SDK文档如下:
1. 数据存放的所需结构体(对讲设备出现呼叫挂断等动作时,回调函数所需)
2. 32位C++方法(32位还是64位提前确认)
//用来初始化SDK类库
//用来注册回调函数
//具体回调函数内容
C#二次调用开发:
[UnmanagedFunctionPointerAttribute(CallingConvention.StdCall)] public delegate void ACTION_CALLBACK(lb_event_message_e userEvent, IntPtr wParam, IntPtr userData); public class LonBonFun { [DllImport("lb_sdk_universal.dll")] public static extern int lb_initialServer(string serverIp, int svrPort); //初始化 [DllImport("lb_sdk_universal.dll")] public static extern int lb_CallActionNotify(ACTION_CALLBACK callback, IntPtr userData); //注册回调函数 [DllImport("lb_sdk_universal.dll")] public static extern int lb_releaseServer(); //释放SDK }
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct ActionParam { public int sender; // 发送端 public int receiver; // 接收端 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)] public string acceptBc; // 广播接收端 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string SessionId; // 会话标识 public int broadId; // 广播组序(标识)/门磁编号 [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 512)] public string rdFile; // 录音文件名 public int atmTerNum; // Atm编号 }
class Program { public static ACTION_CALLBACK callback ; static void Main(string[] args) { int result = LonBonFun.lb_initialServer("192.168.1.94", 5160); Console.WriteLine("已完成初始化"); callback = callFun; LonBonFun.lb_CallActionNotify(callback, (IntPtr)0); Console.ReadKey(); } static private void callFun(lb_event_message_e userEvent, IntPtr wParam, IntPtr userData) { if (userEvent == 9 || userEvent == 10) { ActionParam tActionParam = new ActionParam(); tActionParam = (ActionParam)Marshal.PtrToStructure(wParam,typeof(ActionParam)); Console.WriteLine(tActionParam.rdFile); } } }
注:到这里正文开始了,
方法一:结构体添加属性CharSet = CharSet.Ansi。
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
原因: 首先结构体CharSet属性 是决定字符串封送的方式,共有三种。Unicode将字符串封送为Unicode格式,Ansi为字符串封送为Ansi格式,Auto将字符串随机应变封送
方法二:一般C++结构体用的字符数组char[],但我们在C#一律都换成字节数组byte[], 封送类型从 ByValTStr 改成 ByValArray
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
public byte[] rdFile; // 录音文件名
然后用
System.Text.Encoding.UTF8.GetString(tActionParam .rdFile);
获取,即完成(一般是UTF8)。