1. 程式人生 > >c# 如何 使用共用體

c# 如何 使用共用體

文件輸入 地址 jsb fse 什麽 簡單 int namespace blank

用起來真的方便 轉摘如下:

C#借助FieldOffset屬性實現共用體與強制類型轉換

這兩天被C#的強制類型轉換弄得有點不習慣。事出如此。

在C#中,我打算讀二進制文。文件的結構很簡單,一連串的緊密存儲的int32值,以二進制方式存放。現在我希望隨機讀取第n個int32開始的i個值,並讀入到數組中。結果查一下C#只能讀到byte[]中,要不就是一個個讀出來循環放int[]。追求效率的我當然不希望這樣,如果能像C++那樣將byte[]強制轉換成int[]就好了。例如:

[cpp] view plain copy print?
  1. char tmp[64]; // 16個int。相當於C#的 byte[] tmp = new int[64];
  2. int* dat; // dat的指針。相當於C#的 int[] dat;
  3. ifstream IF(...); // 標準文件輸入流。相當於C#的 FileStream FS = new FileStream(...);
  4. IF.read(tmp, 64); // 讀取64個字節。 相當於C#的 FS.Read(tmp,0,64);
  5. dat = (int*)tmp; // 將tmp數組的首地址轉為int類型,則數組以4個字節為一個int轉換為int型的數組。
  6. // 數據在內存上沒有任何變化,因為數據本來就是int型的。
  7. // 關鍵是這一步在C#中無法直接實現。
  8. for (int i = 0; i < 16; i++)
  9. cout << dat[i] << " "; // 輸出數據。相當於C#的 Console.Write(dat[i]+" ");

在C#中無法直接實現,為此我想了好些辦法,也查了好久,直到我見到了這樣的代碼:

[csharp] view plain copy print?
  1. using System;
  2. using System.IO;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. // 提供各種各樣支持 COM 互操作 及平臺調用服務的成員
  7. using System.Runtime.InteropServices;
  8. namespace test
  9. {
  10. class Program
  11. {
  12. // StructLayout使設計者可以控制類或結構的數據字段的物理布局
  13. // Explicit與FieldOffset一起可以控制每個數據成員的精確位置
  14. [StructLayout(LayoutKind.Explicit)]
  15. public struct S1
  16. {
  17. // FieldOffset控制字段所在的物理位置偏移為0
  18. [FieldOffset(0)]
  19. public byte[] a;
  20. // 同樣偏移為0,開始位置與a重疊了。
  21. [FieldOffset(0)]
  22. public int[] b;
  23. }
  24. static void Main(string[] args)
  25. {
  26. S1 s = new S1(); // 要new,不然b會報“使用了可能未賦值的字段”
  27. s.a=new byte[64];
  28. FileStream FS = new FileStream("E:\\test.txt", FileMode.Open);
  29. // 以s.a來接收文件的數據
  30. FS.Read(s.a,0,64);
  31. // 自己保證讀b的時候不要越界
  32. for (int i = 0; i < 16; i++)
  33. Console.Write(s.b[i]+" "); // 以b來使用數據
  34. Console.ReadKey();
  35. }
  36. }
  37. }

原理實際上跟C++一樣,將一個int[]型的變量指向與byte[]型變量相同的內存區域,跟C++中將dat指向char數組的首地址是一樣的。同樣,這樣的結構體功能與C++的共用體是一樣的,即一個結構可以作為多種數據類型,而具體是什麽類型視情況而定。

測試所使用的文件就不上傳了,有WinHex的可以自己編輯一個,沒有的也可以寫程序將從0xF到0x0的16個數以二進制方式輸出到文件中。文件的內容用WinHex打開以16進制顯示應該如下:

技術分享

c# 如何 使用共用體