国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

C#聯(lián)合Union的實(shí)現(xiàn)方式

2019-11-14 13:29:58
字體:
供稿:網(wǎng)友

一.基礎(chǔ)篇

        C#不像C++,他本身是沒有聯(lián)合Union的,但是可以通過手動控制結(jié)構(gòu)體每個(gè)元素的位置來實(shí)現(xiàn),這需要結(jié)合使用StructLayoutAttribute、LayoutKind以及FieldOffsetAttribute。使用它們的時(shí)候必須引用System.Runtime.InteropServices下面是我寫的模擬U的聯(lián)合。

[StructLayout(LayoutKind.Explicit, Size = 4)]struct U{    [FieldOffset(0)]    public byte b0;    [FieldOffset(1)]    public byte b1;    [FieldOffset(2)]    public byte b2;    [FieldOffset(3)]    public byte b3;     [FieldOffset(0)]    public int i;     [FieldOffset(0)]    public float f;}

        我們知道聯(lián)合中每個(gè)數(shù)據(jù)成員都在相同的內(nèi)存地址開始,所以我們要通過[FieldOffset(0)]應(yīng)用到U的每一個(gè)成員,意思就是讓這些成員處于同一個(gè)開始位置。當(dāng)然,我們得事先告訴.NET這些成員的內(nèi)存布局由我們來作主,所以要使用LayoutKind.Explicit枚舉然后傳遞給StructLayoutAttribute,并應(yīng)用到U上,這樣.Net就不會再干涉該struct的成員在內(nèi)存中的布局了。并且我定義了U的Size為12,當(dāng)然你也可以不定義U的Size。

而且使用聯(lián)合進(jìn)行數(shù)據(jù)轉(zhuǎn)換比BitConverter要快。測試用例如下:

{    DateTime past = DateTime.Now;    int length = 500000 * 3 * 3;    for (int i = 0; i < length; i++)    {        U a = new U();        a.b0 = 0xFF;        a.b1 = 0xFF;        int res = a.i;    }    DateTime now = DateTime.Now;    Console.WriteLine((now - past));} {    DateTime past = DateTime.Now;    int length = 500000 * 3 * 3;    for (int i = 0; i < length; i++)    {        byte[] a = { 0xFF, 0x0F, 0x0F, 0 };        object b = a;        int res = BitConverter.ToInt32(a, 0);    }    DateTime now = DateTime.Now;    Console.WriteLine((now - past));}

二.進(jìn)階篇

之前的方法還存在好多問題,比如數(shù)組沒法放入聯(lián)合中,會提示值和引用沖突什么的。

今天又研究了一下,利用C#中可以使用指針的特性,結(jié)合unsafe和fixed,實(shí)現(xiàn)數(shù)組類型和普通值類型的共存

方法①  數(shù)組類型和普通值類型的共存——固定大小的緩沖區(qū)

利用固定大小的緩沖區(qū)(fixed)實(shí)現(xiàn)數(shù)組類型和普通值類型的共存

[StructLayoutAttribute(LayoutKind.Explicit, Pack = 1)]public unsafe struct A{    [FieldOffset(0)]    public int a;    [FieldOffset(0)]    public byte b;    [FieldOffset(0)]    public float c;    [FieldOffset(0)]    public fixed byte arr[9];};

方法②  結(jié)構(gòu)體轉(zhuǎn)字節(jié)數(shù)組——1).使用聯(lián)合 2).使用指針強(qiáng)制轉(zhuǎn)換

1).使用聯(lián)合,利用一個(gè)和原結(jié)構(gòu)體等長的fixed byte buff[n],這個(gè)buff就是我們要的直接數(shù)組,訪問時(shí)需要通過fixed (byte* ta = a.buff) {}來訪問。

[StructLayoutAttribute(LayoutKind.Explicit, Pack = 1)]public unsafe struct A{    [FieldOffset(0)]    public int a;    [FieldOffset(4)]    public byte b;    [FieldOffset(5)]    public float c;    [FieldOffset(0)]    public fixed byte buff[9];};

2).直接使用指針強(qiáng)制轉(zhuǎn)換,通過fixed,先將結(jié)構(gòu)體轉(zhuǎn)換為void *,再將其轉(zhuǎn)化為byte* b。

fixed (void * ta = &a){    byte* b = (byte*)ta ;}

3).最后通過IntPtr拷貝到C#標(biāo)準(zhǔn)的byte[]中。

byte[] Dbuff = new byte[9];IntPtr pstart = new IntPtr(a);Marshal.Copy(pstart, Dbuff, 0, 9);

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 启东市| 清水河县| 桐梓县| 饶河县| 洪泽县| 五莲县| 达尔| 商南县| 洪泽县| 嘉峪关市| 洪洞县| 汉川市| 永仁县| 台山市| 沈丘县| 兴义市| 安西县| 衡阳县| 普兰店市| 区。| 偃师市| 尼玛县| 长岛县| 台北市| 福州市| 九龙城区| 枣庄市| 特克斯县| 涟水县| 长泰县| 中方县| 郓城县| 平邑县| 家居| 绥江县| 莱芜市| 昆明市| 金坛市| 平顶山市| 潮安县| 大新县|