Hallo,
vielen Dank noch mal an alle. Die Konvertierung funktioniert nun wunderbar
.
So funktioniert die Konvertierung von (packed) Records in TBytes (Array of Byte). Das ist die 1:1-Umsetzung von Adreas Vorschlag. Die Aufrufparameter der Methode Copy mußten ein wenig angepaßt werden, weil es die Methode mit den Aufrufparametern so wohl nicht mehr existiert(?).
Delphi-Quellcode:
class function THalloele.convertStructureToBytes(
astructure: System.Object):TBytes;
var
groesse: Integer;
intp: IntPtr;
begin
groesse := Marshal.&SizeOf(astructure);
SetLength(Result, groesse);
intp := Marshal.AllocHGlobal(groesse);
try
Marshal.StructureToPtr(astructure, intp, false);
Marshal.&Copy(intp, Result, 0, groesse);
finally
Marshal.FreeHGlobal(intp);
end;
end;
Der Versuch über System.Reflection tut leider nicht und mir ist natürlich nicht klar warum, aber ich poste das hier troztdem
.
Delphi-Quellcode:
class function THalloele.reflect(struktur: System.
Object):TBytes;
var
ms :MemoryStream;
typ: System.&
Type;
fields:
Array of FieldInfo;
i :Integer;
value: TObject;
puffer: TBytes;
begin
Result :=
nil;
ms := MemoryStream.Create();
try
try
typ := TypeOf(struktur);
fields := struktur.GetType.GetFields;
for i := Low(fields)
to High(fields)
do
begin
value := fields[i].GetValue(struktur);
puffer := TBytes(value);
ms.
Write(puffer, 0, Marshal.&SizeOf(fields[i].FieldType));
end;
Result := ms.ToArray;
except on e:
Exception do
begin
e.
Message;
end;
end;
finally
ms.Close;
end;
end;
Was mir noch aufgefallen ist:
- Records müssen packed sein und offenbar mit dem Attribut [StructLayout(LayoutKind.Sequential)] deklariert werden, damit sie ge"marshalled" werden können
- Es scheint etwas mühsam die Größe eines Aufzählungstyps zu erzwingen: Mein Weg ist ${Z4} plus [MarshalAs(UnmanagedType.U4)] um ein "WrapperRecord" (Erzwingen einer Breite von hier z.B. 4 Byte. Für bessere Ideen hab ich immer ein offenes Ohr. Das sieht nämlich ziemlich unschön aus
Delphi-Quellcode:
{$Z4}
TBitmapCompression = (BI_RGB = 0, BI_RLE8 = 1, BI_RLE4 = 2);
[StructLayout(LayoutKind.Sequential)]
TBitmapInfoheaderCompression =
packed record
[MarshalAs(UnmanagedType.U4)]
CompressionType: TBitmapCompression;
end;
[StructLayout(LayoutKind.Sequential)]
TBitmapCoreHeader =
packed record // 14 Bytes
Signature :UInt16;
// 'BM'
FileSize :UInt32;
// Dateigröße in Bytes
Reserved :UInt32;
// Unbenutzt
DataOffset :UInt32;
// Datenaufsatzpunkt (Offset)
end;
[StructLayout(LayoutKind.Sequential)]
TBitmapInfoHeader =
packed record // 40 Bytes
Size :UInt32;
// Größe des InfoHeader (fest 40)
Width :UInt32;
// Bitmap-Breite
Height :UInt32;
// Bitmap-Höhe
Planes :UInt16;
// Anzahl der Ebenen/Planes (fest 1)
BitCount :UInt16;
// Bits pro Pixel
// 1 = monochrome palette. NumColors = 1
// 4 = 4bit palletized. NumColors = 16
// 8 = 8bit palletized. NumColors = 256
// 16 = 16bit RGB. NumColors = 65536 (?)
// 24 = 24bit RGB. NumColors = 16M
Compression :TBitmapInfoheaderCompression;
// Kompressionstyp
// 0 = BI_RGB no compression
// 1 = BI_RLE8 8bit RLE encoding
// 2 = BI_RLE4 4bit RLE encoding
ImageSize :UInt32;
// (compressed) Size of Image
// It is valid to set this =0 if Compression = 0
XpixelsPerM :UInt32;
// horizontal resolution: Pixels/meter
YpixelsPerM :UInt32;
// vertical resolution: Pixels/meter
ColorsUsed :UInt32;
// Zahl der tatsächlich verwendeten Farben
ColorsImportant :UInt32;
// Anzahl der wichtigen Farben
// 0 = all
end;
Vielen Dank,
Sascha