2012-05-11 10 views
1

をソケットに書き込む:DelphiはC#の構造体への変換を記録し、私は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で私が見て:C#ので http://i48.tinypic.com/ei6ph5.png

は、私は次のように開始しました構造体のコード:

[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#に変換する必要があります。前もって感謝します。

答えて

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

デルファイIntegerは、C#intと一致します。 Delphi SmallintはC#shortと一致します。 Delphi WordはC#ushortと一致します。

明示的なレイアウトを使用するだけで、人生は難しくなります。問題を簡素化するために、順次とPack属性を使用してください。

あなたが書くの構造体を初期化コードで

:私はあなたが私が何かを確認していませんでしたし、他のエラーがあるかもしれません

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

を書くことを意味していることを期待

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

私は見つけていない。私があなたの場合は、シリアル化された構造体を1バイトずつ出力する診断コードを追加して、正しくシリアル化していることを確認できます。

+0

ありがとうDavid!私はC#構造体とDevice1の値を修正しました。今度は変換が必要CRC計算機能 – Superjet100

+0

@ Superjet100このサイトの表記規則は一度に1つの質問です。私はあなたの質問に答えました。別の質問をしたい場合は、新しい質問をしてください。私はその質問を元の形に戻しました。 –

+0

私は別の質問をしましたhttp://stackoverflow.com/questions/10561007/delphi-function-convert-to-c-sharp-function – Superjet100

関連する問題