title: Send Delphi Record via Socket to C#
body: <p>as the topic mentions I try to send a Delphi record via a socket to C# and try to marhsal it as a struct.</p>
  
  <p>IDE: XE7 and MS Visual Stidio 2010</p>
  
  <pre><code>Type Data = record 
  intDiscipline:         Integer;
  intNumberOfSets:       Integer;
  strPlayer1ID:          string[50];
  strPlayer2ID:          string[50];
  strPlayer3ID:          string[50];
  strPlayer4ID:          string[50];
  strPlayer1Name:        string[50];
  strPlayer2Name:        string[50];
  strPlayer3Name:        string[50];
  strPlayer4Name:        string[50];
  intTournamentProgress: Integer;
  intTableNumber:        Integer;
  end;
  </code></pre>
  
  <p>The C# struct:</p>
  
  <pre><code>[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
      public struct structTiFuRecord
      {
          public int intDiscipline;
          public int intNumberOfSets;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
          public string strPlayer1ID;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
          public string strPlayer2ID;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
          public string strPlayer3ID;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
          public string strPlayer4ID;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
          public string strPlayer1Name;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
          public string strPlayer2Name;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
          public string strPlayer3Name;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 50)]
          public string strPlayer4Name;
          public int intTournamentProgress;
          public int intTableNumber;
      }
  </code></pre>
  
  <p>This is the Delphi record being sent with this code:</p>
  
  <pre><code>IdTCPClient1.Connect;
  
  Data.intDiscipline := 1;
  Data.intNumberOfSets := 5;
  Data.strPlayer1ID := 'Detlef';
  Data.strPlayer2ID := 'Test';
  Data.strPlayer3ID := 'Test';
  Data.strPlayer4ID := 'Test';
  Data.strPlayer1Name := 'Test';
  Data.strPlayer2Name := 'Test';
  Data.strPlayer3Name := 'Test';
  Data.strPlayer4Name := 'Test';
  Data.intTournamentProgress := 99;
  Data.intTableNumber := 1;
  
  networkHeaderRecord.intFlag := 1;
  networkHeaderRecord.intPayload := SizeOf(TiFuRecord);
  networkHeaderRecord.intPacketnumber := 1;
  
  Buffer := RawToBytes(networkHeaderRecord, SizeOf(networkHeaderRecord));
  IdTCPClient1.IOHandler.Write(Buffer);
  
  Buffer := RawToBytes(TiFuRecord, SizeOf(TiFuRecord));
  IdTCPClient1.IOHandler.Write(Buffer);
  </code></pre>
  
  <p>Size Of the Record is 424 Bytes. These are being send.
  In C# (sorry the code was just for testing - it smells ;-( but as their are only 3-4 lines should be fine - hope so)</p>
  
  <pre><code>byte[] arrHeader = new byte[intHeaderLength];
  
              networkStream.Read(arrHeader, 0, intHeaderLength);
  
              phReceive = new ProtocolHeader(arrHeader);
  
              byte[] testArr = new byte[phReceive.Payload];
  
              networkStream.Read(testArr, 0, (int)phReceive.Payload);
  
              test2 = (HelperClass.structTiFuRecord)ByteArrayToStructure(testArr, TiFuRecord, 0);
  </code></pre>
  
  <p>And last but not least here is the code of the function to marshal the byte array:</p>
  
  <pre><code>public static object ByteArrayToStructure(byte[] bytearray, object structureObj, int position)
      {
          int length = Marshal.SizeOf(structureObj);
          IntPtr ptr = Marshal.AllocHGlobal(length);
          Marshal.Copy(bytearray, 0, ptr, length);
          structureObj = Marshal.PtrToStructure(Marshal.UnsafeAddrOfPinnedArrayElement(bytearray, position), structureObj.GetType());
          Marshal.FreeHGlobal(ptr);
          return structureObj;
      } 
  </code></pre>
  
  <p>I am pretty close to a good result. For the integers in the beginning the values are correct. But already the first string is wrong and from their it snowballs. I checked the size the record being send 424 bytes and the struct in c# where I do marshal.sizeOf(struct) ==> 416 bytes. They don't match regarding their size. I assume the size for the strings is wrong. I tried several different ways to socket write on delphi side and also from different posts from here to change the c# struct. Pack param, layout etc.</p>
  
  <p>Support appreciated. Many thanks and best,
  Mäfinho   </p>