【发布时间】:2012-09-28 07:03:54
【问题描述】:
我必须开发一个服务 (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));
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;
在 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)]属性? -- 如何在目标 c# 结构中声明字节数组:作为fixed缓冲区还是使用[MarshalAs(UnmanagedType.ByValArray...)]属性?将输入字节数组编组为最终 C# 结构的更好方法是:使用
Marshal.PtrToStructure或 GCHandle.Alloc(bytes, GCHandleType.Pinned) +AddrOfPinnedObject?
请至少帮助我了解我需要从哪里开始。
【问题讨论】:
-
我认为你给了我们错误的结构声明。您需要给我们一个与电线上的内容相匹配的那个。我猜那是在C程序中。这些对 Delphi
string[]类型的引用让我们感到困惑。 -
@DavidHeffernan,我得到了原始 C 结构的快照。已更新相关问题。
-
你可以接受丹尼斯的回答
-
顺便说一句.. Dennis 的解决方案有效!谢谢
-
是的。你为什么不接受他的回答?