Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi记录到C#结构的转换和从套接字读取_C#_Delphi_Struct_Record - Fatal编程技术网

Delphi记录到C#结构的转换和从套接字读取

Delphi记录到C#结构的转换和从套接字读取,c#,delphi,struct,record,C#,Delphi,Struct,Record,我从socket读取了以下Delphi代码: type RegbusReq2=packed record Funct:char; Device:char; Device1:char; Starting:integer; Quantity:smallint; _CRC:Word; stroka:char;

我从socket读取了以下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;
...
读取数据的计时器滴答声:

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)]
公共结构RegBusRec
{
公共字符功能;
公用字符设备;
公用字符设备1;
公共int启动;
公众数量不足;
公共卫生服务中心;
公共字符信息;
}
...
私有无效计时器1_刻度(对象发送方,事件参数e)
{
字节[]CRCc=新字节[6];
字节[]tmp;
字节[]输出=新字节[25];
RegBusRec req2=新的RegBusRec();
Crc16 Crc16=新的Crc16();
要求2.函数='?';
需求2.设备='0';
需求2.Device1='1';
要求2.启动=2088;
需求2.数量=16;
请求2.消息='\r';
tmp=位转换器.GetBytes(请求2.启动);
CRCc[0]=tmp[0];
CRCc[1]=tmp[1];
CRCc[2]=tmp[2];
CRCc[3]=tmp[3];
tmp=位转换器.GetBytes(请求2.数量);
CRCc[4]=tmp[0];
CRCc[5]=tmp[1];
要求2._CRC=crc16.ComputerTecksum(CRCc);
textBox6.Text+=Environment.NewLine;
textBox6.Text+=“CRC:+req2.\u CRC;
cl.Client.Send(StructureToByteArray(req2));
cl.客户接收(输出);
字节[]val=新字节[4];
val[0]=输出[15];
val[1]=输出[16];
val[2]=输出[17];
val[3]=输出[18];
textBox6.Text+=Environment.NewLine;
textBox6.Text+=“查询:”;
for(int i=0;i
CRC计算正确。但是我把textBox2的号码弄错了。文本-随机数。我怎样才能正确地得到这些数字?提前谢谢

Delphi调试器的Scrrenshot:


好的,我想我可能已经破译了它,但我不会指望它

您似乎在说C代码在
textBox2
中显示了一个意外的值。查看C代码,
textBox2
显示来自
val
的数据。而
val
的赋值方式如下:

val[0] = output[15];
val[1] = output[16];
val[2] = output[17];
val[3] = output[18];
请注意,
output
是一个C#字节数组,因此使用基于零的索引

在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
    输出[0]
    输出[8]
  • val[0]
    输出[9]
    输出[12]
  • val[1]
    output[13]
    output[16]
  • val[2]
    output[17]
    output[20]
  • val[3]
    output[21]
    output[24]
但是您正在将
output[15]
读取到
output[18]
,因此将
val[1]
的一半与
val[2]
的一半结合起来

简而言之,您只需要修复索引


现在,您正在使它变得更加复杂。您可以这样做以获得所有4个单一值:

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

+考虑到问题的不明确性,我感谢侦探的努力。@Superjet这对你有帮助吗?谢谢大卫的帮助!但是现在我不能检查这些修复,因为我的工作中有这个设备-今天是星期天。明天我将对此负责。
single[] val = new single[4];
int byteIndex = 9;
for (int i=0; i<4; i++)
{
    val[i] = BitConverter.ToSingle(val, byteIndex);
    byteIndex += 4;
}
Buffer.BlockCopy(BitConverter.GetBytes(req2.Starting), 0, CRCc, 0, 4);
Buffer.BlockCopy(BitConverter.GetBytes(req2.Quantity), 0, CRCc, 4, 2);