C#讀取C++結構體


工作中遇到C++寫的程序將結構體存儲到Redis中。然后使用C#讀取。其中有幾個需要注意的坑。

1.Struct上的StructLayout中的Pack

  在C#中定義的struct一定要和C++中的對應上 

  [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]

  其中pack 對應C++中De#program pack()

  附結構體轉換代碼:

 1   public StructType ConverBytesToStructure<StructType>(byte[] bytesBuffer)
 2         {
 3             // 檢查長度。
 4             if (bytesBuffer.Length != Marshal.SizeOf(typeof(StructType)))
 5             {
 6                 throw new ArgumentException("bytesBuffer參數和structObject參數字節長度不一致。");
 7             }
 8 
 9             IntPtr bufferHandler = Marshal.AllocHGlobal(bytesBuffer.Length);
10             for (int index = 0; index < bytesBuffer.Length; index++)
11             {
12                 Marshal.WriteByte(bufferHandler, index, bytesBuffer[index]);
13             }
14             StructType structObject = (StructType)Marshal.PtrToStructure(bufferHandler, typeof(StructType));
15             Marshal.FreeHGlobal(bufferHandler);
16             return structObject;
17         }

2.嵌套結構體數組的定義

 當一個結構體中含有另一個結構體數組時,使用如下的定義

     

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 18)]
public StructB[] m_Info;

 

3.字符編碼的轉換(寬窄字符集的問題)

 采用上述StructLayout中的編碼方式和在C++中的一樣

 在C++中 我將Const char*為了將漢字轉化成PB的UTF-8

   

inline string GBKToUTF8(const char* cchar)
{
    std::string strs(cchar);
    string strOutUTF8 = "";
    WCHAR * str1;
    int n = MultiByteToWideChar(CP_ACP, 0, strs.c_str(), -1, NULL, 0);
    str1 = new WCHAR[n];
    MultiByteToWideChar(CP_ACP, 0, strs.c_str(), -1, str1, n);
    n = WideCharToMultiByte(CP_UTF8, 0, str1, -1, NULL, 0, NULL, NULL);
    char * str2 = new char[n];
    WideCharToMultiByte(CP_UTF8, 0, str1, -1, str2, n, NULL, NULL);
    strOutUTF8 = str2;
    delete[]str1;
    str1 = NULL;
    delete[]str2;
    str2 = NULL;
    return strOutUTF8;
}

  在C#端將轉化過的字符串無論使用哪個字符集轉都顯示亂碼。最后調用了C++的方法。

  [DllImport("kernel32.dll")]

        private static extern int MultiByteToWideChar(int CodePage, int dwFlags, string lpMultiByteStr,

                           int cchMultiByte, [MarshalAs(UnmanagedType.LPWStr)]string lpWideCharStr, int cchWideChar);

 public string MByteToWChar(string content, int toEncode)
        {

            //字符編碼轉換 gb2312:936   utf-8:65001  big5:950  latin1:1252

            int len = MultiByteToWideChar(toEncode, 0, content, -1, null, 0);

            char[] temp = new char[len];

            string content1 = new string(temp);

            MultiByteToWideChar(toEncode, 0, content, -1, content1, len);

            return content1;

        }

 


免責聲明!

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



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