c# - 如何将从套接字接收到的字节数组转换为 C# 结构

标签 c# .net delphi

我必须开发一个服务 (C#),它通过 TCP 套接字从网络设备读取数据并将其转换为 C# 结构。

我基于现有的、旧的 Delphi 应用程序,它正在做所有这些事情,我必须在 C# 中迁移逻辑。

编辑: 我从原始数据结构的 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));

有超过 200 个不同类型字段的 Delphi Packed 记录......它看起来大概像:

  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;

要在 Delphi 中将字节数组移动到结构中,有下一个代码:

Move(inBytesArr[StartIdx], DelphiStruct, aMsgSize)

要转换字符串文件(例如 SERIAL_NUMBER)还有这样的代码:

var
  pc: Pchar;
...
pc := @inBytesArr[StartIdx + SerialN_Pos_Idx];
DelphiStruct.SERIAL_NUMBER := pc;

我是第一次处理这样的转换,我不知道从哪里开始:

  • 如何将此结构转换为 C#? -- 我应该使用 LayoutKind.Sequential 还是 LayoutKind.Explicit,或者不使用 [FieldOffset(N)] 属性? -- 我必须如何在 objective-c # 结构中声明字节数组:作为 fixed 缓冲区或使用 [MarshalAs(UnmanagedType.ByValArray...)] 属性?

  • 将输入字节数组编码为最终 C# 结构的更好方法是:使用 Marshal.PtrToStructure 或 GCHandle.Alloc(bytes, GCHandleType.Pinned) + AddrOfPinnedObject?

请至少帮助我了解我需要从哪里开始。

最佳答案

默认情况下,Delphi 的打包记录按单字节边界对齐字段。
因此,你应该使用这样的东西:

[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;    
} 

我唯一不确定的(没有 Deplhi 现在无法测试)是 SERIAL_NUMBER 字段。

更新后:原来,SERIAL_NUMBER 只是一个以 null 结尾的字符串。

关于c# - 如何将从套接字接收到的字节数组转换为 C# 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12635170/

相关文章:

c# - 命名空间 'Data' 中不存在类型或命名空间名称 'System' - 创建 AWS Lambda 函数

Delphi SetLength 用于整数数组

delphi - Delphi Web 和 Web 服务开发当前的选择是什么

delphi - 最有用的 Delphi TStringGrid (Grid) 替代品推荐

c# - 序列化异步 SQLCommand

c# - 当多个线程试图同时在Winforms中使用Invoke更新表单控件时,会发生什么情况?

c# - 在openxml中为Excel添加样式

c# - C#Linq,在两个数字之间的List <int>中找到最小值

c# - 在 C# 中测试某些东西是否是可解析的 XML

c# - 如何在不等待 c# .Net 4.5.1 中的方法响应的情况下迭代调用方法?