1. 程式人生 > 其它 >dotnet C# 將 Byte 二進位制陣列使用不安全程式碼快速轉換為 int 或結構體陣列

dotnet C# 將 Byte 二進位制陣列使用不安全程式碼快速轉換為 int 或結構體陣列

技術標籤:# dotnetcorec#WPFC#dotnetWPF

我在寫一個有趣的 WPF 應用,我會不斷收到從硬體發過來的資料,這些資料被使用 Byte[] 陣列進行傳輸。我想要使用最快的方法轉換為我的 int 陣列或者轉換為結構體陣列,此時可以使用不安全程式碼的方式轉換

假定有一個二進位制陣列 Byte[] 是使用如下程式碼建立的

            var memoryStream = new MemoryStream();
            var binaryWriter = new BinaryWriter(memoryStream);
            for
(int i = 0; i < 100; i++) { binaryWriter.Write(i); } memoryStream.Position = 0; var byteList = memoryStream.ToArray();

也就是說本質這是一個 int 陣列,在獲取到 byteList 時,可以如何快速轉換為 int 陣列使用?如果使用不安全程式碼,那麼轉換邏輯將會非常簡單

            unsafe
            {
                var
length = byteList.Length / sizeof(int); fixed (byte* bytePointer = byteList) { int* intList = (int*) bytePointer; // 這裡就獲取到了 int 陣列,雖然這是一個指標的陣列 for (int i = 0; i < length; i++) { int
value = *intList; Console.WriteLine(value); intList++; } } }

在使用不安全程式碼的時候,需要在專案屬性生成裡面勾選允許不安全程式碼,或者在csproj中新增下面程式碼

  <PropertyGroup>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
  </PropertyGroup>

而如果此時的 byte 陣列的內容實際是某個結構體呢?例如我有一個結構體定義如下

        [StructLayout(LayoutKind.Sequential)]
        struct FooStruct
        {
            public int N1 { get; set; }
            public int N2 { get; set; }
            public int N3 { get; set; }
        }

使用這個程式碼寫入到二進位制

            for (int i = 0; i < 100; i++)
            {
                var fooStruct = new FooStruct()
                {
                    N1 = i,
                    N2 = i,
                    N3 = i
                };
                binaryWriter.Write(fooStruct.N1);
                binaryWriter.Write(fooStruct.N2);
                binaryWriter.Write(fooStruct.N3);
            }

            memoryStream.Position = 0;

            byteList = memoryStream.ToArray();

此時和上面程式碼差不多,只是使用對應的結構體強行轉換指標就可以

            unsafe
            {
                var length = byteList.Length / sizeof(FooStruct);
                fixed (byte* bytePointer = byteList)
                {
                    var fooStructList = (FooStruct*) bytePointer;
                    for (int i = 0; i < length; i++)
                    {
                        var fooStruct = *fooStructList;

                        // 此時就獲取到了結構體陣列
                    }
                }
            }

通過這個方法,雖然是不安全的程式碼,但是能提升很多效能

本文程式碼放在 github 歡迎小夥伴訪問

知識共享許可協議
本作品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。歡迎轉載、使用、重新發布,但務必保留文章署名林德熙(包含連結:http://blog.csdn.net/lindexi_gd ),不得用於商業目的,基於本文修改後的作品務必以相同的許可釋出。如有任何疑問,請與我聯絡。