Einzelnen Beitrag anzeigen

DerSascha

Registriert seit: 14. Jan 2004
Ort: Niedersachsen
18 Beiträge
 
Delphi 7 Enterprise
 
#9

Re: Record zu Array of Byte

  Alt 19. Dez 2005, 19:51
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
  Mit Zitat antworten Zitat