Delphi 记录到 C# 结构的转换并写入套接字
本文关键字:套接字 转换 记录 结构 Delphi | 更新日期: 2023-09-27 18:33:56
我有以下德尔菲代码:
type
RegbusReq2=packed record
Funct:char;
Device:char;
Device1:char;
Starting:integer;
Quantity:smallint;
_CRC:Word; //CRC
stroka:char;
end;
type
crcReg=packed record
buf:array[0..2] of byte;
value:array[0..5] of byte;
end;
type
myRB=record
case byte of
0:(data:RegbusReq2);
1:(Buff:crcReg);
end;
...
procedure TForm1.Button3Click(Sender: TObject);
var
DataReq:myRB;
Output:array[1..15] of Byte;
i:integer;
nomP:string;
st:string;
begin
cs1.Address:=edit5.Text;
cs1.Port := 6001;
typecon:=2;
DataReq.data.Funct:=chr(63);
DataReq.data.Device:=chr(48);
DataReq.data.Device1:=chr(49);
DataReq.data.Starting:=768;
DataReq.data.Quantity:=7;
DataReq.data._CRC:=CRC2(@DataReq.Buff.value,6);
memo1.Lines.Add(IntToStr(DataReq.data._CRC));
DataReq.data.stroka:=chr(13);
application.ProcessMessages();
cs1.Active:=true;
cs1.Socket.SendBuf(DataReq.data,SizeOf(DataReq.data));
application.ProcessMessages();
cs1.Socket.ReceiveBuf(output,SizeOf(output));
application.ProcessMessages();
cs1.Active:=false;
application.ProcessMessages();
if output[1]<>62 then begin
showmessage('îøèáêà ñâÿçè');
exit;
end;
for i:=10 to 15 do
begin
nomp:= nomp + chr(Output[i]);
st:=st + '_' + inttostr(output[i]);
end;
memo1.Lines.Add(inttostr(sizeof(DataReq.data)));
memo1.Lines.Add(st);
memo1.Lines.Add(DataReq.data.Funct);
form1.Caption:=nomp;
Button1.Enabled:=true;
end;
这段代码正在工作,在德尔福我观察:http://i48.tinypic.com/ei6ph5.png
在 C# 中,我从以下结构代码开始:
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi, Size=12)]
struct RegBusRec
{
[FieldOffset(0)]
public char Funct;
[FieldOffset(1)]
public char Device;
[FieldOffset(2)]
public char Device1;
[FieldOffset(6)]
public uint Starting;
[FieldOffset(8)]
public ushort Quantity;
[FieldOffset(10)]
public uint _CRC;
[FieldOffset(11)]
public char Message;
}
我尝试使用代码将 srtuct 转换为字节数组:
public static byte[] Serialize(object obj)
{
Type objectType = obj.GetType();
int objectSize = Marshal.SizeOf(obj);
IntPtr buffer = Marshal.AllocHGlobal(objectSize);
Marshal.StructureToPtr(obj, buffer, false);
byte[] array = new byte[objectSize];
Marshal.Copy(buffer, array, 0, objectSize);
Marshal.FreeHGlobal(buffer);
return array;
}
并发送:
System.Net.Sockets.TcpClient cl = new System.Net.Sockets.TcpClient();
cl.Connect(IPAddress.Parse("xxx.xxx.xxx.xxx"), 6001);
if (cl.Connected)
{
RegBusRec req2 = new RegBusRec();
req2.Funct = '?';
req2.Device = '0';
req2.Device = '1';
req2.Starting = 768;
req2.Quantity = 7;
req2.Message = ''r';
byte[] data = Serialize(req2);
cl.Client.Send(data);
cl.Client.Receive(output);
if (output[0] != 62)
{
Console.WriteLine("Connection error!");
Console.ReadLine();
}
}
但是我从设备收到错误消息。需要更正将德尔菲代码转换为 C#。提前谢谢。
你的结构是错误的。它应该是:
[StructLayout(LayoutKind.Sequential, Pack=1, CharSet=CharSet.Ansi)]
struct RegBusRec
{
public char Funct;
public char Device;
public char Device1;
public int Starting;
public short Quantity;
public ushort _CRC;
public char Message;
}
德尔福Integer
匹配 C# int
.Delphi Smallint
匹配 C# short
。德尔福Word
匹配 C# ushort
.
你使用明确的布局只会让你的生活变得困难。使用顺序和Pack
属性来简化事务。
在初始化结构的代码中,您编写:
req2.Device = '0';
req2.Device = '1';
我希望你的意思是写
req2.Device = '0';
req2.Device1 = '1';
我没有检查其他任何内容,可能还有其他我没有发现的错误。如果我是你,我会添加诊断代码来逐字节发出序列化结构,以便您可以确保正确序列化它。