• 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)。

  • 相关阅读:
    「疫期集训day7」周期
    「字符串」哈希板子
    「疫期集训day6」雨林
    「疫期集训day5」火焰
    「数据结构」对顶堆
    「STL中的常用函数 容器」
    「单调队列优化DP」P2034 选择数字
    bootstrap table使用及遇到的问题
    ArcGIS栅格影像怎么从WGS84地理坐标转成Xian80投影坐标
    arcgis如何求两个栅格数据集的差集
  • 原文地址:https://www.cnblogs.com/HansZimmer/p/10757043.html
Copyright © 2020-2023  润新知