国产探花免费观看_亚洲丰满少妇自慰呻吟_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ā)表
主站蜘蛛池模板: 连平县| 永安市| 清原| 镶黄旗| 广西| 翁牛特旗| 社旗县| 广宗县| 定西市| 友谊县| 甘泉县| 屏东县| 咸宁市| 固始县| 光山县| 阿拉善盟| 太保市| 文山县| 泸水县| 龙山县| 抚顺市| 博爱县| 太谷县| 广东省| 崇州市| 秀山| 全椒县| 乌鲁木齐县| 淳化县| 无棣县| 兴宁市| 远安县| 巫山县| 城固县| 鹰潭市| 南郑县| 连江县| 扎囊县| 吉林市| 利津县| 浪卡子县|