AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Von C++ nach Delphi (Macro)

Ein Thema von Alter Mann · begonnen am 26. Mai 2011 · letzter Beitrag vom 27. Mai 2011
Antwort Antwort
Alter Mann

Registriert seit: 15. Nov 2003
Ort: Berlin
947 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

Von C++ nach Delphi (Macro)

  Alt 26. Mai 2011, 10:29
Hallo,

in der WinNT.h ist das folgende macro definiert:
Code:
//
// 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)))
wie muss das ganze in Delphi aussehen und kann jemand das ganze erklären?

Danke
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Von C++ nach Delphi (Macro)

  Alt 26. Mai 2011, 10:34
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.
$2B or not $2B
  Mit Zitat antworten Zitat
Alter Mann

Registriert seit: 15. Nov 2003
Ort: Berlin
947 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

AW: Von C++ nach Delphi (Macro)

  Alt 26. Mai 2011, 10:51
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.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 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.
$2B or not $2B

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

Registriert seit: 15. Nov 2003
Ort: Berlin
947 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

AW: Von C++ nach Delphi (Macro)

  Alt 26. Mai 2011, 12:26
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.
  Mit Zitat antworten Zitat
Benutzerbild von Der Jan
Der Jan

Registriert seit: 22. Dez 2005
289 Beiträge
 
Delphi XE7 Ultimate
 
#6

AW: Von C++ nach Delphi (Macro)

  Alt 27. Mai 2011, 11:15
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)
Gruß, Jan
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Von C++ nach Delphi (Macro)

  Alt 27. Mai 2011, 11:22
Code:
CONTAINING_RECORD(Addr, MyType, Var3) = Addr - sizeof(Typ2) - sizeof(Typ1)

Dank der Speicherausrichtung, kann das schnell mal schief laufen.

Delphi-Quellcode:
MyType = record
  Var1: Byte;
  Var2: LongInt;
end;
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.
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von Der Jan
Der Jan

Registriert seit: 22. Dez 2005
289 Beiträge
 
Delphi XE7 Ultimate
 
#8

AW: Von C++ nach Delphi (Macro)

  Alt 27. Mai 2011, 11:35
Dank der Speicherausrichtung, kann das schnell mal schief laufen.
Diese muss man natürlich ausschalten. Das war vorausgesetzt
Gruß, Jan
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Von C++ nach Delphi (Macro)

  Alt 27. Mai 2011, 16:11
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)
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:36 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz