西西軟件園多重安全檢測下載網(wǎng)站、值得信賴的軟件下載站!
軟件
軟件
文章
搜索

首頁編程開發(fā)其它知識 → Marshal類的兩個(gè)方法StructureToPtr和PtrToStructure實(shí)現(xiàn)序列化

Marshal類的兩個(gè)方法StructureToPtr和PtrToStructure實(shí)現(xiàn)序列化

相關(guān)軟件相關(guān)文章發(fā)表評論 來源:西西整理時(shí)間:2011/5/28 18:59:56字體大小:A-A+

作者:西西點(diǎn)擊:1512次評論:0次標(biāo)簽: Marshal

  • 類型:英文字庫大。29KB語言:中文 評分:10.0
  • 標(biāo)簽:
立即下載

我們主要是使用Marshal類里的兩個(gè)方法:

第一個(gè)是StructureToPtr,將數(shù)據(jù)從托管對象封送到非托管內(nèi)存塊。

第二個(gè)是PtrToStructure,將數(shù)據(jù)從非托管內(nèi)存塊封送到新分配的指定類型的托管對象。

只要有了這兩個(gè)相互轉(zhuǎn)換的方法,我們就可以實(shí)現(xiàn)序列化了。

首先我們先來看下序列化

序列化:
有一個(gè)前提條件,那就是我們必須要知道需要序列化對象的大小。

第一步:我們先求出對象的大小,然后在非托管內(nèi)存中給它分配相應(yīng)的內(nèi)存大小。

第二步:接著我們就把這個(gè)對象封送到剛分配出來的內(nèi)存中,之后我們會得到一個(gè)分配出來的內(nèi)存塊首地址指針。

第三步:最后我們可以通過這個(gè)首地址指針,從指針?biāo)傅奈恢锰庨_始,拷貝數(shù)據(jù)到指定的byte[]數(shù)組中,拷貝的長度就是我們?yōu)檫@個(gè)對象分配出來的內(nèi)存大小,得到byte[]數(shù)據(jù)后,下面的事情我就不用多說了,你可以保存到數(shù)據(jù)庫或者文件中。

反序列化:
序列化的時(shí)候我們先將一個(gè)對象封送到了非托管內(nèi)存塊中,然后再把內(nèi)存塊中的數(shù)據(jù)讀到byte[]數(shù)組中,

現(xiàn)在我們反序列化

第一步:我們先求出對象的大小,然后在非托管內(nèi)存中給它分配相應(yīng)的內(nèi)存大小。

第二步:然后把這個(gè)byte[]數(shù)據(jù)拷貝到非托管內(nèi)存塊中。

第三步:最后再從內(nèi)存塊中封送指定大小的數(shù)據(jù)到對象中。

有一個(gè)地方需要注意,那就是因?yàn)橐妙愋偷膶ο笪覀兪菬o法求的它的實(shí)際大小的,所以這里的對象我們只能使用非托管對象,比如struct結(jié)構(gòu)體。

所以,當(dāng)我們只是用來存儲數(shù)據(jù),不涉及任何操作的對象,我們可以把它作為一個(gè)結(jié)構(gòu)體來處理,這樣我們在序列化的時(shí)候可以節(jié)省空間開銷。

因?yàn)槟闳绻阋怯闷匠5男蛄谢椒ㄈバ蛄谢粋(gè)類對象,他所需要的空間開銷是要大于你去序列化一個(gè)具有相同結(jié)構(gòu)的struct對象。

下面是代碼: 


public static class MyConverter
{
/// <summary>
/// 由結(jié)構(gòu)體轉(zhuǎn)換為byte數(shù)組
/// </summary>
public static byte[] StructureToByte<T>(T structure)
{
int size = Marshal.SizeOf(typeof(T));
byte[] buffer = new byte[size];
IntPtr bufferIntPtr = Marshal.AllocHGlobal(size);
try
{
Marshal.StructureToPtr(structure, bufferIntPtr, true);
Marshal.Copy(bufferIntPtr, buffer, 0, size);
}
finally
{
Marshal.FreeHGlobal(bufferIntPtr);
}
return buffer;
}

/// <summary>
/// 由byte數(shù)組轉(zhuǎn)換為結(jié)構(gòu)體
/// </summary>
public static T ByteToStructure<T>(byte[] dataBuffer)
{
object structure = null;
int size = Marshal.SizeOf(typeof(T));
IntPtr allocIntPtr = Marshal.AllocHGlobal(size);
try
{
Marshal.Copy(dataBuffer, 0, allocIntPtr, size);
structure = Marshal.PtrToStructure(allocIntPtr, typeof(T));
}
finally
{
Marshal.FreeHGlobal(allocIntPtr);
}
return (T)structure;
}
}

//////////////////////////////////測試代碼///////////////////////////////////
class Program
{
static void Main(string[] args)
{
Student student1 = new Student { Name = "胡昌俊", ID = 2 };
Console.WriteLine("序列化前=> 姓名:{0} ID:{1}", student1.ID, student1.Name);

byte[] bytes = MyConverter.StructureToByte<Student>(student1);
Student sudent2 = MyConverter.ByteToStructure<Student>(bytes);

Console.WriteLine("序列化后=> 姓名:{0} ID:{1}", sudent2.ID, sudent2.Name);
Console.Read();
}
}

public struct Student
{
public int ID { get; set; }
public string Name { get; set; }
}

    相關(guān)評論

    閱讀本文后您有什么感想? 已有人給出評價(jià)!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過難過
    • 5 囧
    • 3 圍觀圍觀
    • 2 無聊無聊

    熱門評論

    最新評論

    發(fā)表評論 查看所有評論(0)

    昵稱:
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字?jǐn)?shù): 0/500 (您的評論需要經(jīng)過審核才能顯示)