C#中使用指针转换数据类型[C#/unsafe]
今日因為一個同事說起,在原來的舊系統中使用指針做數據轉換很方便,比如要把浮點數轉化為數組,也或者是字符串的相互轉換;當然,大家都知道c#中實現指針只需要寫入unsafe,編譯選項把“允許不安全代碼”開啟即可;他提出這種需求也不無道理,因為要和工控的下位機通訊,自行轉換還是比較麻煩,使用指針的話將變的容易許多;具體的實現我編寫了一個類,詳細的作法見代碼;實現了int/float/double轉byte[]三種數據類型的互換,其實說白了就是C的翻版,呵呵;?
可以參見MS對不安全代碼的描述內容如下:
盡管實際上對?C?或?C++?中的每種指針類型構造,C#?都設置了與之對應的引用類型,但仍然會有一些場合需要訪問指針類型。例如,當需要與基礎操作系統進行交互、訪問內存映射設備,或實現一些以時間為關鍵的算法時,若沒有訪問指針的手段,就不可能或者至少很難完成。為了滿足這樣的需求,C#?提供了編寫不安全代碼的能力。?
?
在不安全代碼中,可以聲明和操作指針,可以在指針和整型之間執行轉換,還可以獲取變量的地址,等等。在某種意義上,編寫不安全代碼很像在?C#?程序中編寫?C?代碼。?
?
無論從開發人員還是從用戶角度來看,不安全代碼事實上都是一種“安全”功能。不安全代碼必須用修飾符?unsafe?明確地標記,這樣開發人員就不會誤用不安全功能,而執行引擎將確保不會在不受信任的環境中執行不安全代碼。?
另外,估計會有人說 System.Runtime.InteropServices 的Marshal類已經實現了,MS的描述如下:
Marshal類提供了一個方法集,這些方法用于分配非托管內存、復制非托管內存塊、將托管類型轉換為非托管類型,此外還提供了在與非托管代碼交互時使用的其他雜項方法。
目前我對它還并不十分了解,這個也不是目前重點,重點是C#原來使用指針和C一樣的方便,另外,熟悉指針操作的高淫或是.net類庫高手,本代碼免看了;?
以下是源碼(文末是測試代碼下載),代碼在公司寫好了,不過沒帶回家,又重寫了個:?
using?System;?
using?System.Runtime.InteropServices;?
?
namespace?CSPointer?
{?
????///?<summary>?
????///?PointerConvert?的摘要說明。?
????///?指針轉換類?
????///?通過指針的方式更改數據類型?
????///?支持:byte?<->?int/float/double?
????///??????string?類型可以通過?
????///??????System.Text.Encoding進行編碼?
????///?用途:數據傳輸?
????///?
????///?作者:蕭寒?
????///?http://www.cnblogs.com/chinasf?
????///?mailluck@Gmail.com?
????///?最后更新日期:2005.5.27?
????///?</summary>?
????public?unsafe?class?PointerConvert?
????{?
????????public?PointerConvert(){;}?
?
????????///?<summary>?
????????///?轉換Int數據到數組?
????????///?</summary>?
????????///?<param?name="data"></param>?
????????///?<returns></returns>?
????????public?static?byte[]?ToByte(int?data)?
????????{?
????????????unsafe??
????????????{?
????????????????byte*?pdata?=?(byte*)&data;?
????????????????byte[]?byteArray?=?new?byte[sizeof(int)];?
????????????????for?(int?i?=?0;?i?<?sizeof(int);?++i)?
????????????????????byteArray[i]?=?*pdata++;?
????????????????return?byteArray;?
????????????}?
????????}?
?????????
?
????????///?<summary>?
????????///?轉換float數據到數組?
????????///?</summary>?
????????///?<param?name="data"></param>?
????????///?<returns></returns>?
????????public?static?byte[]?ToByte(float?data)?
????????{?
????????????unsafe??
????????????{?
????????????????byte*?pdata?=?(byte*)&data;?
????????????????byte[]?byteArray?=?new?byte[sizeof(float)];?
????????????????for?(int?i?=?0;?i?<?sizeof(float);?++i)?
????????????????????byteArray[i]?=?*pdata++;?
????????????????return?byteArray;?
????????????}?
????????}?
?
????????///?<summary>?
????????///?轉換double數據到數組?
????????///?</summary>?
????????///?<param?name="data"></param>?
????????///?<returns></returns>?
????????public?static?byte[]?ToByte(double?data)?
????????{?
????????????unsafe??
????????????{?
????????????????byte*?pdata?=?(byte*)&data;?
????????????????byte[]?byteArray?=?new?byte[sizeof(double)];?
????????????????for?(int?i?=?0;?i?<?sizeof(double);?++i)?
????????????????????byteArray[i]?=?*pdata++;?
????????????????return?byteArray;?
????????????}?
????????}?
?
?
????????///?<summary>?
????????///?轉換數組為整形?
????????///?</summary>?
????????///?<param?name="data"></param>?
????????///?<returns></returns>?
????????public?static?int?ToInt(byte[]?data)?
????????{?
????????????unsafe?
????????????{?
????????????????int?n?=?0;?
????????????????fixed(byte*?p=data)?
????????????????{?
????????????????????n?=?Marshal.ReadInt32((IntPtr)p);?
????????????????}?
????????????????return?n;?
????????????}?
????????}?
?
????????///?<summary>?
????????///?轉換數組為float?
????????///?</summary>?
????????///?<param?name="data"></param>?
????????///?<returns></returns>?
????????public?static?float?ToFloat(byte[]?data)?
????????{?
????????????float?a=0;?
????????????byte?i;?
?????????????
????????????byte[]?x?=?data;?
????????????void?*pf;?
????????????fixed(byte*?px=x)?
????????????{?
????????????????pf?=&a;?
????????????????for(i=0;i<data.Length;i++)?
????????????????{?
????????????????????*((byte?*)pf+i)=*(px+i);?
????????????????}?
????????????}?
?
????????????return?a;?????????????
????????}?
?????
????????///?<summary>?
????????///?轉換數組為Double?
????????///?</summary>?
????????///?<param?name="data"></param>?
????????///?<returns></returns>?
????????public?static?double?ToDouble(byte[]?data)?
????????{?
????????????double?a=0;?
????????????byte?i;?
?????????????
????????????byte[]?x?=?data;?
????????????void?*pf;?
????????????fixed(byte*?px=x)?
????????????{?
????????????????pf?=&a;?
????????????????for(i=0;i<data.Length;i++)?
????????????????{?
????????????????????*((byte?*)pf+i)=*(px+i);?
????????????????}?
????????????}?
????????????return?a;?
????????}?
?
?
????}?
}?
?
總結
以上是生活随笔為你收集整理的C#中使用指针转换数据类型[C#/unsafe]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 编程语言API性能大比拼
- 下一篇: 保证你现在和未来不失业的十种关键技术