一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - C# - C#如何利用結(jié)構(gòu)體對固定格式數(shù)據(jù)進(jìn)行解析

C#如何利用結(jié)構(gòu)體對固定格式數(shù)據(jù)進(jìn)行解析

2022-02-19 15:41小書丶 C#

這篇文章主要為大家詳細(xì)介紹了C#利用結(jié)構(gòu)體對固定格式數(shù)據(jù)進(jìn)行解析,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文為大家分享了c#利用結(jié)構(gòu)體解析固定格式數(shù)據(jù)的具體代碼,供大家參考,具體內(nèi)容如下

制定了一個通訊協(xié)議,然后其數(shù)據(jù)部分有如下格式。

C#如何利用結(jié)構(gòu)體對固定格式數(shù)據(jù)進(jìn)行解析

第三列代表的是字節(jié)數(shù),第4列是數(shù)據(jù)類型。

當(dāng)傳輸或者收到一個byte數(shù)組的時候(下面hex數(shù)據(jù)),按照對應(yīng)格式進(jìn)行解析,解析方法有很多種,網(wǎng)上看到了一種方式是以結(jié)構(gòu)體的方式來解析的,類似c/c++方式。

hex數(shù)據(jù):01 01 00 00 10 44 65 76 69 63 65 20 4e 61 6d 65 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 31 2e 30 2e 30 00 00 00 00 00 00 00 00 00 00 00 41 42 43 31 32 33 34 35 36 37 00 00 00 00 00 00 56 31 2e 30 2e 30 00 00 00 00 00 00 00 00 00 00 32 30 31 38 2f 31 2f 32 32 00 00 00 00 00 00 00

定義一個結(jié)構(gòu)體:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using system.runtime.interopservices;
[structlayoutattribute(layoutkind.sequential, charset = charset.ansi, pack = 1)]
  public struct infostruct
  {
    [marshalas(unmanagedtype.u1, sizeconst = 1)]
    public byte slotnum;
    [marshalas(unmanagedtype.u4,sizeconst =4)]
    public uint32 moduleid;
    [marshalas(unmanagedtype.byvalarray,sizeconst =32)]
    public char[] devicename;
    [marshalas(unmanagedtype.byvalarray, sizeconst = 16)]
    public char[] hardwarenum;
    [marshalas(unmanagedtype.byvalarray, sizeconst = 16)]
    public char[] hardwareversion;
    [marshalas(unmanagedtype.byvalarray, sizeconst = 16)]
    public char[] softwareversion;
    [marshalas(unmanagedtype.byvalarray, sizeconst = 16)]
    public char[] softwaredate;
  }

再寫一個輔助解析的靜態(tài)幫助類,該類提供將結(jié)構(gòu)體轉(zhuǎn)成byte數(shù)組和byte數(shù)組轉(zhuǎn)成結(jié)構(gòu)體功能,我在原來的方法上面添加了泛型,功能不變:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public static class structhelper
  {
    /// <summary>
    /// byte數(shù)組轉(zhuǎn)目標(biāo)結(jié)構(gòu)體
    /// </summary>
    /// <param name="bytes">byte數(shù)組</param>
    /// <param name="type">目標(biāo)結(jié)構(gòu)體類型</param>
    /// <returns>目標(biāo)結(jié)構(gòu)體</returns>
    public static t bytetostuct<t>(byte[] databuff_) where t:struct
    {
      type t = typeof(t);
      //得到結(jié)構(gòu)體大小
      int size = marshal.sizeof(t);
      //數(shù)組長度小于結(jié)構(gòu)體大小
      if (size > databuff_.length)
      {
        return default(t);
      }
 
      //分配結(jié)構(gòu)體大小的內(nèi)存空間
      intptr structptr = marshal.allochglobal(size);
      //將byte數(shù)組cpoy到分配好的內(nèi)存空間內(nèi)
      marshal.copy(databuff_, 0, structptr, size);
      //將內(nèi)存空間轉(zhuǎn)換為目標(biāo)結(jié)構(gòu)體
      t obj = (t)marshal.ptrtostructure(structptr, t);
      //釋放內(nèi)存空間
      marshal.freehglobal(structptr);
      return obj;
    }
    /// <summary>
    /// 結(jié)構(gòu)體轉(zhuǎn)byte數(shù)組
    /// </summary>
    /// <param name="objstuct">結(jié)構(gòu)體</param>
    /// <returns>byte數(shù)組</returns>
    public static byte[] stucttobyte(object objstuct)
    {
      //得到結(jié)構(gòu)體大小
      int size = marshal.sizeof(objstuct);
      //創(chuàng)建byte數(shù)組
      byte[] bytes = new byte[size];
      //分配結(jié)構(gòu)體大小的空間
      intptr structptr = marshal.allochglobal(size);
      //將結(jié)構(gòu)體copy到分配好的內(nèi)存空間內(nèi)
      marshal.structuretoptr(objstuct, structptr, false);
      //從內(nèi)存空間copy到byte數(shù)組
      marshal.copy(structptr, bytes, 0, size);
      //釋放內(nèi)存空間
      marshal.freehglobal(structptr);
      return bytes;
    }
  }

好了現(xiàn)在結(jié)構(gòu)體有了,轉(zhuǎn)換方法也有了那么就來使用一下吧!先將結(jié)構(gòu)體轉(zhuǎn)為byte數(shù)組,然后再還原結(jié)構(gòu)體試試:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
static void main(string[] args)
    {
      try
      {
        infostruct info;
        info.hardwarenum = "1.0.0".tochararray();
        info.hardwareversion = "abc1234567".tochararray();
        info.devicename = "device name1".tochararray();
        info.moduleid = 0x10000001;
        info.slotnum = 1;
        info.softwaredate = "2018/1/22".tochararray();
        info.softwareversion = "v1.0.0".tochararray();
        var b = structhelper.stucttobyte(info);
        console.writeline("struct length:"+b.length);
        console.writeline("hex:"+bytetoolshelper.bytearraytohexstring(b," "));
        var s = structhelper.bytetostuct<infostruct>(b);
        console.writeline("name:"+s.devicename.getstring());
      }
      catch (exception ex)
      {
        console.writeline(ex.message);
      }
      console.readkey();
 
    }

其中bytetoolshelper.bytearraytohexstring是我封裝的一個函數(shù),將byte數(shù)組轉(zhuǎn)為hex字符串,方便顯示和調(diào)試可以不用管。

然后調(diào)試運(yùn)行得到結(jié)果:

C#如何利用結(jié)構(gòu)體對固定格式數(shù)據(jù)進(jìn)行解析

我擦,這是什么情況?什么叫“未能封送類型,因?yàn)榍度霐?shù)組實(shí)例的長度與布局中聲明的長度不匹配?????”

調(diào)試一下就可以發(fā)現(xiàn)實(shí)際結(jié)構(gòu)體標(biāo)記的sizeconst和tochararray()函數(shù)得到的長度并不一樣,字符串通過tochararray()得到的長度不足導(dǎo)致出現(xiàn)這個異常。

既然是長度不足,那么就想辦法補(bǔ)足吧。

寫個靜態(tài)擴(kuò)展方法,包含上面的getstring擴(kuò)展方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static char[] getfixlengthchar(this string s,int length)
    {
      char[] chaval = new char[length];
      array.copy(s.padright(length, '\0').tochararray(), chaval, length);
      return chaval;
    }
    public static string getstring(this char[] cc)
    {
      return getstring(cc,true);
    }
    public static string getstring(this char[] cc,bool istrimend)
    {
      if (istrimend)
      {
        return new string(cc).trimend('\0');
      }
      else
      {
        return new string(cc);
      }
    }

getfixlengthchar是將字符串轉(zhuǎn)為固定長度char數(shù)組,getstring是從char數(shù)組轉(zhuǎn)為字符串,因?yàn)橛?#39;\0'可以用trimend函數(shù)去掉,這樣字符串后面就不會有一排空的了。

我們再試試結(jié)果:

C#如何利用結(jié)構(gòu)體對固定格式數(shù)據(jù)進(jìn)行解析

沒問題!成功的轉(zhuǎn)換和還原了。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://www.cnblogs.com/Iamsorry/archive/2018/01/29/8378061.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本天堂视频在线观看 | 性白俄罗斯高清xxxxx | 好男人影视社区www在线观看 | 91麻豆国产福利在线观看 | 美女的让男人桶爽30分钟的 | 美女黄a| 男同桌脱我奶罩吸我奶作文 | 无颜之月全集免费观看 | 国产精品亚洲午夜不卡 | 国产剧情一区二区三区 | 国产成人a v在线影院 | 青青操在线播放 | 国产精品怡红院在线观看 | 99久久6er热免费精品 | 久久国产视频网站 | 日韩免费一区 | 好男人在线观看免费高清2019韩剧 | 色橹橹| 精品AV综合导航 | 亚洲欧美成人综合在线 | 国产高清在线精品一区二区三区 | 4tube高清性欧美 | 国产精品免费拍拍拍 | 日韩成人免费aa在线看 | 日本护士撒尿 | 99re8在这里只有精品23 | 小草视频免费观看在线 | 国产小视频在线免费观看 | 亚洲天堂日韩在线 | 羞羞一区二区三区四区片 | 国产精品suv一区二区 | 丝袜老师好湿好紧我要进去了 | 国产一区二区三区久久精品小说 | 国产精品原创巨作无遮挡 | 国产精品天天看特色大片不卡 | 午夜特级毛片 | 黑人k8经典 | 操熟美女又肥又嫩的骚屁股 | 国内精品久久久久影院中国 | 亚洲欧美日韩精品高清 | 亚洲精品免费在线观看 |