您好,登錄后才能下訂單哦!
這標題或許有些大,叫做“CSharp非托管內存拷貝轉換數據”之類的也許更貼近本文主題。考慮到本文有擴展的可能,就先這樣子吧!本篇的內容主要包括:
1、簡介
2、利用非托管內存轉換基本類型數組
1、簡介
C#專門提供了非托管內存操作的功能類System.Runtime.InteropServices.Marshal。做過C/C++互操作的朋友應該對這個類有所了解吧!
非托管內存使用的好處是方便,能夠快速操作內存,在一些類型數據轉換的時候能夠減少運算量,提升運算速度;缺點就是會花費更多的內存,而且操作非托管內存很容易引起內存泄漏,所以使用的時候需要萬分小心,在給程序員帶來方便的同時,也會挖下一些隱藏的坑!
2、利用非托管內存轉換基本類型數組
/// <summary> /// short數組轉換成byte數組 /// </summary> /// <param name="source"></param> /// <param name="target"></param> /// <param name="sourceLen">要Copy的source數組個數</param> public static void CopyMemFromShort(short[] source, byte[] target, int sourceLen) { IntPtr tmpPtr = IntPtr.Zero; try { tmpPtr = Marshal.AllocHGlobal(sourceLen * 2); // 申請內存 //copy數據到指定非托管內存地址 Marshal.Copy(source, 0, tmpPtr, sourceLen); //copy非托管內存數據到指定byte數組 Marshal.Copy(tmpPtr, target, 0, sourceLen * 2); Marshal.FreeHGlobal(tmpPtr); // 清空申請的非托管內存 } catch (Exception ex) { if (tmpPtr != IntPtr.Zero) Marshal.FreeHGlobal(tmpPtr); throw new Exception("內存操作失敗:" + ex.ToString()); } }
當然,大家完全可以用System.Buffer.BlockCopy()方法來實現以上的操作,本方法可以完全當做另一種思路,而且由于會申請額外的空間,在大量數據的copy時候,效率上也不及BlockCopy。
一般來講,操作非托管內存的使用步驟包括
a.申請內存;b.拷貝數據到非托管內存;c.拷貝非托管內存數據到托管內存; d.釋放內存。
申請內存
System.IntPtr tmpPtr = Marshal.AllocHGlobal(sourceLen); // 申請內存
上面的代碼就從非托管內存中申請了sourceLen長度的內存(字節為單位),返回的結構體為申請內存地址的指針,申請內存可能出現OutofMemory的異常,使用的時候要注意。
拷貝數據到非托管內存、拷貝非托管內存數據到托管內存
//copy數據到指定非托管內存地址 Marshal.Copy(source, 0, tmpPtr, sourceLen); //copy非托管內存數據到指定byte數組,short->byte 2個字節->1個字節,所以長度要* 2 Marshal.Copy(tmpPtr, target, 0, sourceLen * 2);
以上兩個步驟都是用的同一個方法的不同重裝。Marshal.Copy既支持從非托管內存Copy數據,也支持將數據Copy到非托管內存,詳細介紹可見MSDN文檔
釋放內存
Marshal.FreeHGlobal(tmpPtr); // 清空申請的非托管內存
最后釋放內存,這一步很重要,用了的非托管內存必須手動釋放!
上面的方法只演示了從short[]轉換到byte[]的轉換,其它轉換如byte[]->short[]。int[]->byte[]。int[]->short[]都類似,編碼的時候需要將它們在內存中占用的字節數搞清楚,避免內存溢出等問題的出現。
詳細的轉換代碼我會在最后一篇給出,下一篇會說到結構體在內存中的轉換方法。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。