如何在c#中读取打包记录中的Delphi固定大小字符串数组

Jam*_*ass 8 c# arrays delphi struct marshalling

我需要将数据库中的blob字段读入ac#app.

但是,blob字段是由Delphi App使用以下方法写入数据库的:

 procedure WriteABlob(Blob : TBlobField; var Buffer; size : integer);
 var 
     s : String;
 begin
     setlength(s,size);
     move(buffer,s[1],Size);
     Blob.Value := S;
 end;
Run Code Online (Sandbox Code Playgroud)

写入数据库的结构不是一个简单的结构,包含类似的东西

MyVariable : Array[0..3] of String[80];
Run Code Online (Sandbox Code Playgroud)

或者更糟糕的是其中一些包含

MyRecord = Packed Record
case byte of
    1: (
        iValue:Integer;
       )
    2: (
        cValue:Char;
       )
end;
Run Code Online (Sandbox Code Playgroud)

我一直在尝试从数据库读取字节然后使用

Marshal.PtrToStructure()
Run Code Online (Sandbox Code Playgroud)

为了将它移动到结构中

我的结构定义如下:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1, Size = 10710)]
    public struct MyBlobField
    {
        ...
        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.AnsiBStr,SizeConst = SpecificArraySize)]
        public String[] ArrayofFixedLengthStrings;
        ...
    }
Run Code Online (Sandbox Code Playgroud)

但是在调用Marshal.PtrToStructure()时出现错误:

无法封送"MyBlobField"类型的字段"ArrayofFixedLengthStrings":无效的托管/非托管类型组合(String []必须与LPStr,LPWStr,BStr或LPTStr的ArraySubType配对).

我想知道是否有一个我可以在CustomMarshaler上定义的属性,它接受与String []的配对

我有什么想法可以将blob的内容读入c#?

Jam*_*ass 2

弄清楚了...

将 struct String20 声明为

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct String20
    {
        [MarshalAs(UnmanagedType.U1)]
        public byte StringSize;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
        public String Value;
    }
Run Code Online (Sandbox Code Playgroud)

显然,固定长度字符串(即 delphi ShortString)开头的字符串大小标识符只有 1 个字节。然后将 header_identifiers 的定义更改为:

       [MarshalAs(UnmanagedType.ByValArray, SizeConst = max_header_identifiers)]
        public String20[] header_identifiers;
Run Code Online (Sandbox Code Playgroud)

还发现 Delphi Packed Boolean 需要转换为

[MarshalAs(UnmanagedType.I1)]
public bool BooleanVar;
Run Code Online (Sandbox Code Playgroud)