1

I have following Delphi code:

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;

This code is working and in Delphi I watch: http://i48.tinypic.com/ei6ph5.png

In C# I've started with following code of struct:

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

And I try to convert srtuct to byte array with code:

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

And send it:

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

But I get wrong message from device. Need to correct convert Delphi code to C#. Thanks in advance.

1 Answer 1

5

Your struct is wrong. It should be:

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

Delphi Integer matches C# int. Delphi Smallint matches C# short. Delphi Word matches C# ushort.

Your use of explicit layout just makes life hard for you. Use sequential and the Pack attribute to simplify matters.

In the code where you initialise a struct you write:

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

I expect that you meant to write

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

I've not checked anything else, and there may be other errors that I have not found. If I were you I would add diagnostics code to emit byte by byte your serialized struct so that you can be sure that you are serializing it correctly.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks David! I'he have corrected C# struct and value of Device1. Now I need conversion CRC calc function
@Superjet100 The conventions at this site are one question at a time. I answered your question. If you want to ask another question, make a new question for that. I reverted the question to its original form.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.