我已经提出了基于Reading binary file from delphi和Proper struct layout from delphi packed record
的当前c#结构现在我的问题是我没有从文件中获取正确的值
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
struct test {
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 3)]
string field1;
...
}
她是德尔福记录
char3 = Array[0..2] of Char;
test = Record
field1: char3;
...
编辑:
正如我在大卫回答的评论中所说。问题是我缺少字符串的一部分。在按照David的回答使用byte[]
代替string
后,我的代码现在正在运行。
以防有人偶然发现这个delphi record to C#,这有点令人困惑,因为它假定delphi字符串是以空值终止的。
同样关于StructLayout
Pack
属性,只要尝试将此设置为1,即使您要转换的Delphi记录没有指明它。如果我遗漏了有关Pack
的内容,请在评论中更正我。感谢
至于我的最终结构:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct test {
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
byte[] field1;
...
}
答案 0 :(得分:1)
问题中代码的正确性完全取决于Char
。
Char
是WideChar
的别名,是16位类型。Char
是AnsiChar
的别名,是8位类型。因此,如果您使用的是Delphi 2009之前的Delphi版本,那么您的代码是正确的。否则您的C#代码应该用CharSet.Ansi
替换CharSet.Unicode
。
另一个区别是C#代码坚持要求数组为空终止,而Delphi代码则不需要。因此,如果您的Delphi代码想要将所有三个元素都用作非空值,那么您需要避免在C#端使用string
。它会变成:
[StructLayout(LayoutKind.Sequential)]
struct test {
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
byte[] field1;
...
}
用于Unicode前Delphi或
[StructLayout(LayoutKind.Sequential)]
struct test {
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
char[] field1;
...
}
for Unicode Delphi。