Delphi记录到C#结构的转换和从套接字读取
我从socket读取了以下Delphi代码: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;
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);