1

I have come up with current c# struct based on Reading binary file from delphi and Proper struct layout from delphi packed record

Now my problem is I am not getting the correct values from the file

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct test {
  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 3)]
  string field1;
  ...
}

Hers is the delphi record

char3 = Array[0..2] of Char;

test = Record
  field1: char3;
  ...

Edit:

As I said in the comment on David's answer. The problem is that I am missing parts of the string. After following David's answer which is to use byte[] instead of string, my code is now working.

Just in case someone stumbled upon this delphi record to C#, which is a bit confusing since it assumes that the delphi strings are null-terminated.

Also regarding the StructLayout Pack attribute, just try setting this to 1 even though the Delphi record you are converting doesn't indicate it. If I am missing something regarding Pack please correct me in the comment. Thanks

As for my final struct:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct test {
  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
  byte[] field1;
  ...
}
pikunuxew
  • 13
  • 4

1 Answers1

1

The correctness of the code in the question depends entirely on what Char is.

  • In Delphi 2009 and later, Char is an alias to WideChar which is a 16 bit type.
  • In earlier versions, Char is an alias to AnsiChar which is a 8 bit type.

So, your code is correct if you are using a version of Delphi earlier than Delphi 2009. Otherwise your C# code should replace CharSet.Ansi with CharSet.Unicode.

The other difference is that the C# code insists on the array being null-terminated, whereas the Delphi code need not. So if your Delphi code wants to use all three elements as non-null values then you would need to avoid using a string on the C# side. It would become:

[StructLayout(LayoutKind.Sequential)]
struct test {
  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
  byte[] field1;
  ...
}

for pre-Unicode Delphi, or

[StructLayout(LayoutKind.Sequential)]
struct test {
  [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
  char[] field1;
  ...
}

for Unicode Delphi.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Its earlier than 2009, I also tried the CharSet.Unicode just to check maybe it will work. Anyways, the problem is that I am just getting 2 characters for field1 instead of 3. – pikunuxew Sep 28 '17 at 09:08
  • Only the string fields have a problem, particularly field1 gets the first 2 but field 5 is missing the first character. – pikunuxew Sep 28 '17 at 09:10
  • Ok I will try using byte[]. I already noticed that they are not null-terminated while looking at the file in hex but disregarded it since I read somewhere here in SO that strings should be used. Too bad I did not bookmarked that one. Thanks – pikunuxew Sep 28 '17 at 09:53