![]() |
Von C++ nach Delphi (Macro)
Hallo,
in der WinNT.h ist das folgende macro definiert:
Code:
wie muss das ganze in Delphi aussehen und kann jemand das ganze erklären?
//
// Calculate the address of the base of the structure given its type, and an // address of a field within the structure. // #define CONTAINING_RECORD(address, type, field) ((type *)( \ (PCHAR)(address) - \ (ULONG_PTR)(&((type *)0)->field))) Danke |
AW: Von C++ nach Delphi (Macro)
Geht nicht.
Außer du schreibst dir einen Preprozessor für den Compiler, welcher sowas vorher noch schnell ausrechnet. Lösung: Rechenvorschrift erkennen und die entsprechenden Werte überall direkt einsetzen. Eventuell kann man sich auch ein Programm schreiben (falls es das nicht schon gibt), welches den wert berechnet, falls es mehrere werden. Oder man muß weg von Konstanten und kann dann aus dem Makro eine Funktion machen. |
AW: Von C++ nach Delphi (Macro)
Ach himitsu, du bist wie immer so aufbauend; Danke!
Das Problem ist nur das dieses macro innerhalb einer procedur aufgerufen wird und da ich nicht weis was da genau passiert, kann ich es nicht so einfach 'nachbauen'. Verwendet wird es in dem USBView Beispiel des WinDDK. |
AW: Von C++ nach Delphi (Macro)
Delphi-Quellcode:
Das Problem ist jetzt allerdings, daß du dieses nichtmal direkt übersetzen kanns.
function CONTAINING_RECORD(Address: Pointer; cType: PTypeInfo; Field: String): Pointer;
begin Result := PAnsiChar(Address) - LongInt(@cType(nil).{Field}); end; 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:
Es gibt für dieses in Delphi leider keinerlei Sprachfeatures, welche sowas direkt bieten.
type
TMyType = record abc: LongInt; def: Byte; end; Pneu := CONTAINING_RECORD(P, TMyType, def); // wäre dann Pneu := Pointer(Integer(P) - 4); > 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:
Es sei denn du nimmst mehrere Funktionen, für jeweils eine cType-Field-Kombination.
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;
Delphi-Quellcode:
Dann jeweils eine Kopie davon erstellen und dort {Type} und {Field} ersetzen.
function ContainingRecord_{Type}_{Field}(Address: Pointer): Pointer; overload;
begin Result := Pointer(Integer(@Address) - Integer(P{Type}(nil).{Field})); end; |
AW: Von C++ nach Delphi (Macro)
Danke, die Realisierung wird allerdings etwas dauern.
Zum Glück ist der Typ bekannt 'LIST_ENTRY', mal sehen wie ich mich anstelle. Werde mich bestimmt nochmal melden. |
AW: Von C++ nach Delphi (Macro)
Wenn dir der Typ und Feld bekannt sind (und selbige idealerweise auch noch konstant bleiben), dann kennst du doch den Offset des Feldes und ziehst diesen einfach von der gegebenen Adresse ab und hast die gesuchte Basisadresse.
Code:
//Pseudocode, nicht schlagen :)
type MyType = record Var1: Typ1; Var2: Typ2; Var3: Typ3; Var4: Typ4; end; CONTAINING_RECORD(Addr, MyType, Var3) = Addr - sizeof(Typ2) - sizeof(Typ1) |
AW: Von C++ nach Delphi (Macro)
Zitat:
Dank der Speicherausrichtung, kann das schnell mal schief laufen.
Delphi-Quellcode:
Laut deiner Berechnung/Zählung würde Var2 einen Offset von 1 haben, da SizeOf(Byte) = 1, aber standardmäig wird man einen Offset von 4 vorfinden.
MyType = record
Var1: Byte; Var2: LongInt; end; |
AW: Von C++ nach Delphi (Macro)
Zitat:
|
AW: Von C++ nach Delphi (Macro)
Theoretisch hätte ich ja eine Funktion, ohne RTTI, welche die Ausrichtung berechnet, aber so optimal ist diese Lösung dann garnicht.
(Ich glaub ich hatte das aktuell im himXML mit hochgeladen ... siehe Record-Serialisierung) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:06 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz