So I have a Delphi application that is taking records of various types, throwing them on a memorystream via stream.Write(record, sizeof(record))
and sending them over a named pipe.
Take this Delphi record :
Type TAboutData = record
Version : array[0..4] of Byte;
Build : Word;
BuildDate : TDateTime;
SVNChangeset : Word;
end;
When this is sent over the named pipe, it comes out like this in a byte[] array :
Length: 22 Bytes
0x06, 0x00, 0x00, 0x00, 4 bytes for array
0x00, 0x00, 0x00, 0x00, 2 bytes for build, 2 bytes for alignment?
0x15, 0xA3, 0x86, 0x3F, 8 bytes for double
0xBC, 0x44, 0xE4, 0x40,
0xA3, 0x02, 0x00, 0x00, 2 bytes for SVNChangeSet, 2 bytes alignment?
0x00, 0x00, 2 bytes for something else?
Alignment Questions
- I believe this is called alignment in 4-byte boundries, correct?
- What are the last two bytes for?
Now I'm trying (unsuccessfully) to marshal this into a C# struct.
[StructLayout(LayoutKind.Sequential)]
struct TAboutInfo
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] Version;
public ushort Build;
public double BuildDate;
public ushort SVNChangeSet;
}
IntPtr ptr = Marshal.AllocHGlobal(bytebuffer.Length);
Marshal.Copy(ptr, bytebuffer, 0, bytebuffer.Length);
TAboutInfo ta = (TAboutInfo)Marshal.PtrToStructure(ptr, typeof(TAboutInfo));
Marshal.FreeHGlobal(ptr);
C# Questions
- This simply does not work, and I can't really figure out how to account for the alignment. I've tried explicit offsets but I'm coming up short.
- I have many record types, some with members that are dynamic arrays of other records. I'd rather come up with a robust solution to converting these byte arrays into structures or objects.
array[0..4] of Byte
contains 5 bytes, not 4. What is SizeOf(record) in Delphi? I guess it's 20, not 22. – nullptr