Как прочитать массив Delphi из строк фиксированного размера в упакованной записи в c # - PullRequest
8 голосов
/ 03 февраля 2010

Мне нужно прочитать поле большого двоичного объекта из базы данных в приложение ac #.

Однако поле большого двоичного объекта было записано в базу данных приложением Delphi с использованием следующего метода:

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

Структура, записанная в базу данных, не является простой структурой и содержит такие вещи, как

MyVariable : Array[0..3] of String[80];

или, что еще хуже, некоторые из них содержат

MyRecord = Packed Record
case byte of
    1: (
        iValue:Integer;
       )
    2: (
        cValue:Char;
       )
end;

Я пытался прочитать в байтах отбазы данных, а затем с помощью

Marshal.PtrToStructure()

переместить ее в структуру

Моя структура определяется следующим образом:

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

Но я получаю ошибку, когдавызов Marshal.PtrToStructure ():

Невозможно упорядочить поле 'ArrayofFixedLengthStrings' типа 'MyBlobField': недопустимая комбинация управляемого / неуправляемого типа (String [] должна быть в паре с ArraySubType из LPStr, LPWStr,или LPTStr).

Мне было интересно, есть ли атрибут, который я мог бы определить в CustomMarshaler, который бы принимал соединение со строкой []

Любые идеи, как я мог бы прочитатьКонтеноты капли в c #?

Ответы [ 2 ]

2 голосов
/ 04 февраля 2010

Разобрался ...

Объявлен 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;
    }

Очевидно, что идентификатор размера строки в начале строки фиксированной длины (то есть delphi ShortString) является только1 байтЗатем изменил определение header_identifiers на:

       [MarshalAs(UnmanagedType.ByValArray, SizeConst = max_header_identifiers)]
        public String20[] header_identifiers;

Также обнаружил, что Delphi Packed Boolean нужно привести к

[MarshalAs(UnmanagedType.I1)]
public bool BooleanVar;
0 голосов
/ 04 февраля 2010

Мой первый комментарий заключается в том, что «String [80]» является строкой фиксированной длины (которую легче обрабатывать в структуре), а в C # вы пытаетесь поместить ее в «String []» - которая на самом деле является ссылкой (указателем) на строку.

Мой следующий комментарий заключается в том, что в худшем случае вы можете попробовать прочитать его в массив байтов, извлечь нужные вам байты и манипулировать ими в структуре назначения.

...