2010-02-03 7 views
8
liest

Ich muss ein Blob-Feld aus einer Datenbank in eine C# -App lesen.Wie man ein Delphi-Array mit festen Größen innerhalb eines gepackten Datensatzes in C#

jedoch das BLOB-Feld in der Datenbank durch eine Delphi App geschrieben wurde die folgende Methode verwendet:

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

Die Struktur in die Datenbank geschrieben ist keine einfache Struktur und enthält Dinge wie

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

oder schlechter einige von ihnen enthalten

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

Ich habe versucht r eading in dem Bytes aus der Datenbank und dann

Marshal.PtrToStructure() 

, um mit zu bewegen, in die Struktur

Meine Struct ist wie folgt definiert:

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

Aber ich erhalte eine Fehlermeldung beim Aufruf Marshal.PtrToStructure():

kann nicht Marschall Feld 'ArrayofFixedLengthStrings' vonTyp'MyBlobField': Ungültige verwaltete/nicht verwaltete Typkombination (String [] muss mit einem ArraySubType von LPStr, LPWStr, BStr oder LPTStr gepaart werden).

Ich habe mich gefragt, ob es ein Attribut war ich auf einem Custom definieren könnte, die die Verbindung mit einem String akzeptieren würde []

Irgendwelche Ideen, wie ich den Inhalt des Blobs in C# lesen konnte?

+0

gegossen werden müssen, ist es wirklich ein AnsiBstr und kein reguläres Bstr (das heißt Unicode). Das ist ziemlich nicht Standard. –

+1

Ältere Versionen von Delphi (einschließlich D2007) standardisiert auf Ansi anstelle von Unicode. –

Antwort

2

es herausgefunden ...

ein struct String20 erklärt wurde

[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; 
    } 

Anscheinend ist der String-Länge Kennung am Beginn einer festen Länge string (d.h ein Delphi Short) nur 1 Byte ist. verändert dann die Definition von header_identifiers zu:

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

auch festgestellt, dass Delphi Packed Boolean als

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

Mein erster Kommentar ist, dass die "String [80]" ist eine Zeichenfolge fester Länge (die in einer Struktur einfacher sein sollte), und in C# Sie versuchen, es in eine "String []" - Dies ist eigentlich eine Referenz (Zeiger) auf eine Zeichenfolge.

Mein nächster Kommentar ist, dass Sie im schlimmsten Fall versuchen könnten, es in ein Array von Bytes zu lesen und die benötigten Bytes herauszuziehen und sie in die Zielstruktur zu manipulieren.

+0

Ich habe versucht, es in eine Reihe von String zu setzen! Meine anderen Gedanken waren in der Richtung des Lesens in einer Ganzzahl, gefolgt von 3 AnsiBStr in normalen Strings (d. H. Flattern Sie das Array und ignorieren Sie seine Größe Parameter). Bedeutet das, wenn ich eine ICustomMarshal-Schnittstelle verwende und einen Zeiger anstelle eines Objekts zurückgebe, kann ich einen CustomMarshaler für ein Array verwenden? Ich nahm an, dass es ein Attribut war. Dies ist nicht der einzige Blob, den wir haben, und dieser allein ist 10k. Ich würde es vorziehen, die Route der Byte-Arrays noch nicht zu gehen. –

Verwandte Themen