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#。提前谢谢。

Delphi 记录到 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';
我没有

检查其他任何内容,可能还有其他我没有发现的错误。如果我是你,我会添加诊断代码来逐字节发出序列化结构,以便您可以确保正确序列化它。