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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM