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

C# 如何在c中读取打包记录中固定大小字符串的Delphi数组#,c#,delphi,arrays,struct,marshalling,C#,Delphi,Arrays,Struct,Marshalling,我需要将一个blob字段从数据库读入c#app [MarshalAs(UnmanagedType.I1)] public bool BooleanVar; 但是,Delphi应用程序使用以下方法将blob字段写入数据库: procedure WriteABlob(Blob : TBlobField; var Buffer; size : integer); var s : String; begin setlength(s,size); move(buff

我需要将一个blob字段从数据库读入c#app

[MarshalAs(UnmanagedType.I1)]
public bool BooleanVar;
但是,Delphi应用程序使用以下方法将blob字段写入数据库:

 procedure WriteABlob(Blob : TBlobField; var Buffer; size : integer);
 var 
     s : String;
 begin
     setlength(s,size);
     move(buffer,s[1],Size);
     Blob.Value := S;
 end;
[MarshalAs(UnmanagedType.I1)]
public bool BooleanVar;
写入数据库的结构不是简单的结构,它包含以下内容

MyVariable : Array[0..3] of String[80];
[MarshalAs(UnmanagedType.I1)]
public bool BooleanVar;
或者更糟的是,其中一些含有

MyRecord = Packed Record
case byte of
    1: (
        iValue:Integer;
       )
    2: (
        cValue:Char;
       )
end;
[MarshalAs(UnmanagedType.I1)]
public bool BooleanVar;
我一直在尝试从数据库中读取字节,然后使用

Marshal.PtrToStructure()
[MarshalAs(UnmanagedType.I1)]
public bool BooleanVar;
以便将其移动到结构中

[MarshalAs(UnmanagedType.I1)]
public bool BooleanVar;
我的结构定义如下:

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1, Size = 10710)]
    public struct MyBlobField
    {
        ...
        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.AnsiBStr,SizeConst = SpecificArraySize)]
        public String[] ArrayofFixedLengthStrings;
        ...
    }
[MarshalAs(UnmanagedType.I1)]
public bool BooleanVar;
但调用Marshal.PtrToStructure()时出错:

[MarshalAs(UnmanagedType.I1)]
public bool BooleanVar;
无法封送字段 类型为的“ArrayOfficedLengthStrings” “MyBlobField”:无效 托管/非托管类型组合 (字符串[]必须与 LPStr、LPWStr、BStr或的阵列子类型 LPTStr)

[MarshalAs(UnmanagedType.I1)]
public bool BooleanVar;
我想知道是否有一个属性可以在CustomMarshaler上定义,它可以接受与字符串[]的配对

[MarshalAs(UnmanagedType.I1)]
public bool BooleanVar;

我的第一个评论是“String[80]”是一个固定长度的字符串(在结构中应该更容易处理),而在c#中,您试图将其放入一个“String[]”中,它实际上是一个指向字符串的引用(指针)

[MarshalAs(UnmanagedType.I1)]
public bool BooleanVar;
我的下一个评论是,在最坏的情况下,您可以尝试将其读入一个字节数组,然后取出所需的字节并将其操纵到目标结构中。

找到了答案

[MarshalAs(UnmanagedType.I1)]
public bool BooleanVar;
将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;
    }
[MarshalAs(UnmanagedType.I1)]
public bool BooleanVar;
显然,固定长度字符串(即delphi ShortString)开头的字符串大小标识符只有1字节。 然后将标题_标识符的定义更改为:

       [MarshalAs(UnmanagedType.ByValArray, SizeConst = max_header_identifiers)]
        public String20[] header_identifiers;
[MarshalAs(UnmanagedType.I1)]
public bool BooleanVar;
还发现Delphi压缩布尔值需要转换为

[MarshalAs(UnmanagedType.I1)]
public bool BooleanVar;

它是否真的是AnsiBstr而不是常规的Bstr(即unicode)。这是非常不标准的。旧版本的Delphi(包括D2007)是在Ansi而不是unicode上标准化的。我试图把它放在一个字符串数组中!我的其他想法是将一个整数后跟3个AnsiBStr读入普通字符串(即展平数组并忽略其大小参数)。这是否意味着如果我使用ICustomMarshal接口并返回指针而不是对象,我就可以使用CustomMarshaler来处理数组?我认为这是一种属性。这不是我们仅有的一个这样的blob,仅这一个就有10k,我不想走字节数组的路线。