1

私は次のDelphiコードを持っています:

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;

このコードは機能しており、Delphiで私は見ています: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();
                }
}

しかし、デバイスから間違ったメッセージが表示されます。DelphiコードをC#に正しく変換する必要があります。前もって感謝します。

4

1 に答える 1

5

あなたの構造体は間違っています。そのはず:

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

DelphiIntegerはC#と一致しintます。DelphiSmallintはC#と一致しshortます。DelphiWordはC#と一致しushortます。

明示的なレイアウトを使用すると、生活が困難になります。シーケンシャルとPack属性を使用して、問題を単純化します。

構造体を初期化するコードでは、次のように記述します。

req2.Device = '0';
req2.Device = '1';

私はあなたが書くつもりだったと思います

req2.Device = '0';
req2.Device1 = '1';

私は他に何もチェックしていません、そして私が見つけていない他のエラーがあるかもしれません。もし私があなたなら、シリアル化された構造体をバイトごとに出力する診断コードを追加して、正しくシリアル化されていることを確認できるようにします。

于 2012-05-11T11:59:51.237 に答える