[英]How to byte array received from socket, to C# structure
I have to Develop a Service (C#) which read data from Network Device via TCP Socket and convert this is C# structure. 我必须开发一个服务(C#),它通过TCP Socket从网络设备读取数据并转换它是C#结构。
I am basing on existing, old Delphi application which is doing all this stuff and I have to migrate logic in C#. 我基于现有的旧Delphi应用程序,它正在做所有这些事情,我必须在C#中迁移逻辑。
EDITED: I got a snapshot from C-Source of original data-structure: 编辑:我从原始数据结构的C-Source获得了一个快照:
struct _RequestMsgStruct
{
UCHAR request_ver; //In DELPHI it is represented as Byte
USHORT mac_addr[3]; /* MAC Address */
UINT product_type; //In DELPHI - Cardinal
UCHAR supply_type; //In DELPHI - Byte
short reserved0; //In DELPHI - SmallInt
UCHAR oper_ver[4]; //In DELPHI - CARDINAL !!!
USHORT brd_id; //In DELPHI - WORD
unsigned short exp_id1; //In DELPHI - WORD
//In DELPHI - string[15]; //Array [0..15] of char;
UCHAR serial_no[16]; /* Serial Number. 16th char have to be NULL */
UCHAR _name[32]; /* Name */ //Length of payload may vary //In DELPHI - string[31]
float data_avg; //In DELPHI - Single
ULONG key[5]; //In DELPHI - array [0..19] of Byte
}__attribute__ ((packed));
There is Delphi Packed record with over 200 fields of different types... it look approximately like: Delphi Packed记录包含200多个不同类型的字段......看起来大致如下:
TREC_DATA = packed record
ID : Byte;
MAC_ADDRESS : array [0..5] of Byte;
fieldCard : cardinal;
fieldSI : SmallInt;
fieldW : WORD;
SERIAL_NUMBER : string[15]; //Array [0..15] of char;
fieldSingle : Single;
fieldArrOfB : array [0..19] of Byte;
end;
To move byte array to structure in Delphi there is next code: 要在Delphi中将字节数组移动到结构,有下一个代码:
Move(inBytesArr[StartIdx], DelphiStruct, aMsgSize)
To convert string files (eg SERIAL_NUMBER) there is also such code: 要转换字符串文件(例如SERIAL_NUMBER),还有这样的代码:
var
pc: Pchar;
...
pc := @inBytesArr[StartIdx + SerialN_Pos_Idx];
DelphiStruct.SERIAL_NUMBER := pc;
I having deal with such conversion for first time and I don't know from where to start: 我第一次处理这种转换,我不知道从哪里开始:
How to convert this structure to c#? 如何将此结构转换为c#? -- Should I use LayoutKind.Sequential
or LayoutKind.Explicit
, with or wiyhout [FieldOffset(N)]
attribute? - 我应该使用LayoutKind.Sequential
或LayoutKind.Explicit
,还是wiyhout [FieldOffset(N)]
属性? -- How I have to declare array of bytes in target c# structure: as fixed
buffer or using [MarshalAs(UnmanagedType.ByValArray...)]
attribute? - 我如何在目标c#结构中声明字节数组:作为fixed
缓冲区或使用[MarshalAs(UnmanagedType.ByValArray...)]
属性?
Which is better way to marshal input bytes array to final C# structure: using Marshal.PtrToStructure
or GCHandle.Alloc(bytes, GCHandleType.Pinned) + AddrOfPinnedObject
? 哪种方法可以将输入字节数组编组到最终的C#结构:使用Marshal.PtrToStructure
或GCHandle.Alloc(bytes,GCHandleType.Pinned)+ AddrOfPinnedObject
?
Please help me, at least, to get start point in understating from where i need to start. 请帮助我,至少,从我需要开始的地方获得低估的起点。
By default, Delphi's packed records align fields by single byte boundary. 默认情况下,Delphi的打包记录按单字节边界对齐字段。
Hence, you should use something like this: 因此,你应该使用这样的东西:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct TREC_DATA
{
public byte ID;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[] MAC_ADDRESS;
public uint fieldCard;
public short fieldSI;
public ushort fieldW;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] SERIAL_NUMBER;
public float fieldSingle;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public byte[] fieldArrOfB;
}
The only thing I'm not sure (and can't test now without Deplhi), is a SERIAL_NUMBER field. 我唯一不确定(现在没有Deplhi就无法测试)的是SERIAL_NUMBER字段。
After your update: in original, SERIAL_NUMBER is just a null-terminated string. 更新后:原来,SERIAL_NUMBER只是一个以空字符结尾的字符串。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.