Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.287 Beiträge
 
Delphi 12 Athens
 
#4

AW: Von C++ nach Delphi (Macro)

  Alt 26. Mai 2011, 11:34
Delphi-Quellcode:
function CONTAINING_RECORD(Address: Pointer; cType: PTypeInfo; Field: String): Pointer;
begin
  Result := PAnsiChar(Address) - LongInt(@cType(nil).{Field});
end;
Das Problem ist jetzt allerdings, daß du dieses nichtmal direkt übersetzen kanns.

cType it wohl ein Record-Typ
Field ist der Name eines Feldes in diesem Record

Den Typ könntest du als PTypeInfo übergeben

TypeInfo(TMyType)
und dann müßtest du über die RTTI den Offset dieses Feldes in dem record rausfinden

Danach dann diesen Offset von Address abziehen und das wäre das Ergebnis.

Delphi-Quellcode:
type
  TMyType = record
    abc: LongInt;
    def: Byte;
  end;

Pneu := CONTAINING_RECORD(P, TMyType, def);

// wäre dann
Pneu := Pointer(Integer(P) - 4);
Es gibt für dieses in Delphi leider keinerlei Sprachfeatures, welche sowas direkt bieten.
> keine Makros
> und man kann Variablen\Typen\Felder nicht direkt "namentlich" über einen "String" ansprechen.

cType könnte man noch als Gernic übergeben, aber beim Field war's das dann ... dort kommt man ohne RTTI nicht weiter.
Delphi-Quellcode:
function TTheClass.ContainingRecord<cType>(Address: Pointer; Field: String): Pointer;
var
  Offset: Integer;
begin
  Offset := {RTTI nach dem Offset von Field in cType fragen};
  Result := PAnsiChar(Address) - i;
end;
Es sei denn du nimmst mehrere Funktionen, für jeweils eine cType-Field-Kombination.
Delphi-Quellcode:
function ContainingRecord_{Type}_{Field}(Address: Pointer): Pointer; overload;
begin
  Result := Pointer(Integer(@Address) - Integer(P{Type}(nil).{Field}));
end;
Dann jeweils eine Kopie davon erstellen und dort {Type} und {Field} ersetzen.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (26. Mai 2011 um 11:42 Uhr)
  Mit Zitat antworten Zitat