2012-05-12 13 views
1

から読み取る私はソケットからの読み込みDelphiのコードを以下ました:Delphiのレコードを変換し、ソケット

type 
    RegbusReq2=packed record 
    Funct:char;    
    Device:char;    
    Device1:char; 
    Starting:integer;  
    Quantity:smallint;  
    _CRC:Word;    
    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; 

    type 
    outVal=packed record 
    cap:array[0..8] of byte; 
    val:array[0..3] of single; 
    end; 

    type 
    outValBuff=record 
    case byte of 
    0:(val:outVal); 
    1:(Buff:array [1..25] of byte); 
    end; 


var 
    Form1: TForm1; 
    hCommFile:THandle; 
    typeCon:byte;  
    cs1: TClientSocket; 
... 

タイマーデータを読み込むfoはダニ:

Procedure TForm1.Timer1Timer(Sender: TObject); 
var 
    DataReq:myRB; 
    output:outValbuff; 
    Wr,Rd:Cardinal; 
    i:integer; 
    st:string; 
begin 
    //çàïîëíåíèå çàïðîñà 
    DataReq.data.Funct:=chr(63); //êîìàíäà "?" 
    DataReq.data.Device:=chr(48);  //íîìåð ïðèáîðà ñò 
    DataReq.data.Device1:=chr(49); //íîìåð ïðèáîðà ìëàäøèé 
    DataReq.data.Starting:=2088;  //àäðåñ â äåñ ôîðì 
    DataReq.data.Quantity:=16;  //ðàçìåð äàííûõ 
    DataReq.data._CRC:=CRC2(@DataReq.Buff.value,6);  //ÊÑ 
    DataReq.data.stroka:=chr(13);    //ïåðåâîä ñòðîêè 

PurgeComm(hCommFile,PURGE_RXCLEAR or PURGE_TXCLEAR); 
if typecon=1 then begin //COM-ïîðò 
WriteFile(hCommFile,DataReq.data,SizeOf(DataReq.data),Wr,nil); 
ReadFile(hCommFile,Output.buff,SizeOf(Output.Buff),Rd,nil); 
end; 
if typecon=2 then begin //ethernet 
    cs1.Active:=true; 
    cs1.Socket.SendBuf(DataReq.data,SizeOf(DataReq.data)); 
    cs1.Socket.ReceiveBuf(output.buff,SizeOf(Output.Buff)); 
    cs1.Active:=false; 
end; 

for i:=1 to 25 do 
st:=st + '_' + inttostr(output.buff[i]); 
memo1.Lines.Add(st); 

edit1.Text:=FloatToStr(Round(output.val.val[0] 
*exp(2*ln(10)))/(exp(2*ln(10)))); 
edit2.Text:=FloatToStr(Round(output.val.val[1] 
*exp(2*ln(10)))/(exp(2*ln(10)))); 
edit3.Text:=FloatToStr(Round(output.val.val[2] 
*exp(2*ln(10)))/(exp(2*ln(10)))); 
edit4.Text:=FloatToStr(Round(output.val.val[3] 
*exp(2*ln(10)))/(exp(2*ln(10)))); 

end; 

私はC#のコードを以下ました:

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]   
     public struct RegBusRec 
     { 
      public char Funct; 
      public char Device; 
      public char Device1; 
      public int Starting; 
      public short Quantity; 
      public ushort _CRC; 
      public char Message; 
     } 
... 
private void timer1_Tick(object sender, EventArgs e) 
     { 
      byte[] CRCc = new byte[6]; 
      byte[] tmp; 
      byte[] output = new byte[25]; 
      RegBusRec req2 = new RegBusRec(); 
      Crc16 crc16 = new Crc16(); 
      req2.Funct = '?'; 
      req2.Device = '0'; 
      req2.Device1 = '1'; 
      req2.Starting = 2088; 
      req2.Quantity = 16; 
      req2.Message = '\r'; 
      tmp = BitConverter.GetBytes(req2.Starting); 
      CRCc[0] = tmp[0]; 
      CRCc[1] = tmp[1]; 
      CRCc[2] = tmp[2]; 
      CRCc[3] = tmp[3]; 
      tmp = BitConverter.GetBytes(req2.Quantity); 
      CRCc[4] = tmp[0]; 
      CRCc[5] = tmp[1]; 
      req2._CRC = crc16.ComputeChecksum(CRCc); 
      textBox6.Text += Environment.NewLine; 
      textBox6.Text += "CRC: " + req2._CRC; 
      cl.Client.Send(StructureToByteArray(req2)); 
      cl.Client.Receive(output); 
      byte[] val = new byte[4]; 
      val[0] = output[15]; 
      val[1] = output[16]; 
      val[2] = output[17]; 
      val[3] = output[18]; 
      textBox6.Text += Environment.NewLine; 
      textBox6.Text += "Query: "; 
      for (int i = 0; i < StructureToByteArray(req2).Length; i++) 
      { 
       textBox6.Text += StructureToByteArray(req2)[i] + "_"; 
      } 
      textBox2.Text = BitConverter.ToSingle(val,0).ToString(); 
      textBox6.Text += Environment.NewLine; 
      textBox6.Text += "Data: "; 
      for (int i = 0; i < output.Length; i++) 
      { 
       textBox6.Text += output[i] + "_"; 
      } 
     } 
... 
static byte[] StructureToByteArray(object obj) 
     { 

      int len = Marshal.SizeOf(obj); 
      byte[] arr = new byte[len]; 
      IntPtr ptr = Marshal.AllocHGlobal(len); 
      Marshal.StructureToPtr(obj, ptr, true); 
      Marshal.Copy(ptr, arr, 0, len); 
      Marshal.FreeHGlobal(ptr); 
      return arr; 
     } 

CRC calcが正しく計算されます。しかし、私はtextBox2.Text - 乱数の番号が間違っています。どうやってこの番号を正しく取得できますか?前もって感謝します。 Delphiのデバッガの

Scrrenshot:

enter image description here

答えて

2

OK、私はそれを解読しているかもしれないと思うが、私はそれにはカウントされないだろう。

C#コードが予期しない値をtextBox2に表示しているようです。 C#コードを見るとtextBox2にはvalからのデータが表示されます。 outputは、C#のバイト配列であるので、ゼロベースのインデックスを使用していることを

val[0] = output[15]; 
val[1] = output[16]; 
val[2] = output[17]; 
val[3] = output[18]; 

注:そしてvalはそうのように割り当てられています。あなたのDelphiコードで

は、一致するデータ構造である:

outVal=packed record 
    cap:array[0..8] of byte; 
    val:array[0..3] of single; 
end; 

outValBuff=record 
    case byte of 
    0:(val:outVal); 
    1:(Buff:array [1..25] of byte); 
end; 

そこで、capは、最初の9つのバイトを消費した後、次の16は、4つの単精度値です。 C#のバイト配列の点で:

  • cap
  • val[2]
  • output[20]から output[17]で、
  • val[1]
  • output[16]から output[13]ある、
  • val[0]
  • output[12]から output[9]ある、
  • output[8]からoutput[0]ありますval[3]output[21]output[24]

しかし、あなたはoutput[18]output[15]を読み取り、そのval[2]の半分でval[1]の半分を兼ね備えています。

要するに、インデックス作成を修正するだけで済みます。


今、あなたはそれが必要となるはるかに複雑になっています。これを行う、

single[] val = new single[4]; 
int byteIndex = 9; 
for (int i=0; i<4; i++) 
{ 
    val[i] = BitConverter.ToSingle(val, byteIndex); 
    byteIndex += 4; 
} 

というよりCRCcにバイト単位で周りのものをコピー:あなたはすべての4つの値のホールドを取得するには、このような何かを行うことができ

Buffer.BlockCopy(BitConverter.GetBytes(req2.Starting), 0, CRCc, 0, 4); 
Buffer.BlockCopy(BitConverter.GetBytes(req2.Quantity), 0, CRCc, 4, 2); 
+0

+1を探偵の努力のための検討します問題の明確さの欠如。 –

+0

@ Superjetこれはあなたを助けますか? –

+0

ダビデに助けてくれてありがとう!しかし、今私は仕事のこのデバイス - 今日は日曜日ですので、この修正をチェックすることはできません。明日私はこれに答えるでしょう。 – Superjet100

関連する問題