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.