我认为编组 Delphi 短字符串的最简洁方法是将其包装在结构中。
[StructLayout(LayoutKind.Sequential)]
public struct DelphiShortString
{
private byte length;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=255)]
private byte[] payload;
public string Value
{
get
{
return Encoding.Default.GetString(payload, 0, length);
}
set
{
length = (byte)Math.Min(value.Length, 255);
payload = Encoding.Default.GetBytes(value.Substring(0, length));
}
}
}
此类型不可 blittable,因此不能用作函数返回值。如果您可以控制 Delphi 代码,那么您可以确保不使用短字符串作为函数返回类型。但是,我怀疑您无法控制它。在这种情况下,您需要结构的 blittable 版本。看起来像这样:
[StructLayout(LayoutKind.Sequential)]
public unsafe struct DelphiShortString
{
private byte length;
private fixed byte payload[255];
public string Value
{
get
{
{
byte[] bytes = new byte[length];
fixed (byte* ptr = payload)
{
Marshal.Copy((IntPtr)ptr, bytes, 0, length);
}
return Encoding.Default.GetString(bytes, 0, length);
}
}
set
{
byte[] bytes = Encoding.Default.GetBytes(value);
length = (byte)Math.Min(bytes.Length, 255);
fixed (byte* ptr = payload)
{
Marshal.Copy(bytes, 0, (IntPtr)ptr, length);
}
}
}
}
这表明 DLL 导出 Delphi 短字符串的设计不佳。这表明该库的作者并未将其设计为与其他编译器兼容。这反过来表明这些函数很可能使用默认的 Delphi 调用约定。这是register,Microsoft 工具不支持。如果我的预感是对的,那么这个 DLL 是不能直接消费的。您需要编写一个适配器 DLL,以公开一个更友好的互操作接口。