Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - benötige Erklärung zu Statement


KainPlan - Di 09.12.08 12:42
Titel: benötige Erklärung zu Statement
Hallo ich bin ein C++ Programmierer und komme hier nicht weiter. ^^

Ich kann mir nicht erklären was die folgenden Statements bedeuten, könnte mir das vielleicht jemand erklären?


Pointer curFrame
CallStack[cnt] = Pointer((PInteger(curFrame) + 4)^ - 4);
curFrame = Pointer(PInteger(curFrame)^ );

also curFrame ist ein Pointer schon klar aber dieses ^ -4 macht mich stuzig. Auch das (curFrame)^
Jemand eine Idee??


Delete - Di 09.12.08 12:48

Ein ^ hinter einer Pointervaraiblen steht für Dereferenzierung.


jaenicke - Di 09.12.08 13:00

Hallo und :welcome: im Forum ;-)

user profile iconKainPlan hat folgendes geschrieben Zum zitierten Posting springen:
Pointer curFrame
CallStack[cnt] = Pointer((PInteger(curFrame) + 4)^ - 4);
curFrame = Pointer(PInteger(curFrame)^ );
Das sieht wie eine Mischung aus C++ und Delphi aus. In Delphi sieht das eher so aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var
  curFrame: Pointer;

begin

  CallStack[cnt] := Pointer((PInteger(curFrame) + 4)^ - 4);
  curFrame := Pointer(PInteger(curFrame)^ );
Funktionieren wird das so aber nicht!
Grund:
Anders als in C++ kannst du mit Pointern nicht direkt rechnen. Du kannst sie zu Integer casten, dann kannst du damit als Integer rechnen. Dann musst du aber Integer(curFrame) nehmen, nicht PInteger.
Wenn du den Pointer als einen Pointer auf einen Integer nehmen willst und um die Größe eines Integers erhöhen willst, dann kannst du Inc benutzen. Dies erhöht einen typisierten Pointer um die Größe des Typs:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var
  curFrame: Pointer;
begin
  curFrame := Pointer(4); // dem Pointer den Wert 4 zuweisen
  Inc(PInteger(curFrame)); // den Pointer auf einen Integer um die Größe eines Integers (4) erhöhen
  ShowMessage(IntToStr(Integer(curFrame))); // den Pointer als Integer in einen String umwandeln und ausgeben
Es sollte 8 ausgegeben werden.

Was möchtest du denn machen? So macht der Quelltext kaum einen Sinn.


KainPlan - Di 09.12.08 15:44

Hi,

und danke erst einmal für das herzliche Willkommen :)
das Problem ist nicht das es im Delphi-Programm nicht funktioniert sondern das ich nicht verstehe was da passiert da ich ja C++ Programmierer bin. :)

aber danke für die fixen Antworten.


jaenicke - Di 09.12.08 15:53

user profile iconKainPlan hat folgendes geschrieben Zum zitierten Posting springen:
das Problem ist nicht das es im Delphi-Programm nicht funktioniert sondern das ich nicht verstehe was da passiert da ich ja C++ Programmierer bin. :)
Das ist aber gar kein funktionierender Delphiquelltext. :nixweiss:

Wie gesagt: es sieht wie eine Mischung aus Delphi und C++ aus, funktioniert aber weder in einer noch der anderen Sprache so, und es fehlt auch Quelltext. Zum Beispiel die Initialisierung des Pointers etc.

Woher hast du denn den Quelltext?


KainPlan - Di 09.12.08 16:27

So hier haste deinen funktionierenden Delphi Quelltext ^^
Der Code dient zur (wie sagt man dazu) verfolgung des CallStacks?


(TCallStack ist ein array von Pointern...)


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
procedure FillCallStack(var St: TCallStack; const NbLevelsToExclude: integer);
var
  StackStart: Pointer;
  StackMax: Pointer;  //the stack can never go beyond - http://msdn.microsoft.com/library/periodic/period96/S2CE.htm
  CurrentFrame: Pointer;
  Count, SkipCount: integer;
begin
  FillChar(St, SizeOf(St), 0); 
  asm
    mov EAX, FS:[4]       
    mov StackMax, EAX
    mov StackStart, EBP   
  end;
  CurrentFrame:= StackStart;
  Count:= 0;
  SkipCount:= 0;
  while (longint(CurrentFrame) >= longint(StackStart)) and (longint(CurrentFrame) < longint(StackMax)) and (Count <= StoredCallStackDepth) do
    begin
      if SkipCount >= NbLevelsToExclude then
        begin
          St[Count]:= Pointer(PInteger(longint(CurrentFrame) + 4)^ - 4); //Hier steckt der wurm im verständniss
          Count:= Count + 1;
        end;
      CurrentFrame:= Pointer(PInteger(CurrentFrame)^); // genauso wie hier
      SkipCount:= SkipCount + 1;
    end;
end;


also wenn ich das richtig interpretiere und davon ausgehe das wie DeddyH gesagt hat ^ eine dereferenzierung ist müsste es in c++ so aussehen?

long* ptr = (long*) long(curFrame) + 4;
long* st = (long*) ((*ptr) - 4);

oh man ^^


jaenicke - Di 09.12.08 16:53

Vergleich mal mit deinem Code oben ;-):
user profile iconKainPlan hat folgendes geschrieben Zum zitierten Posting springen:

Quelltext
1:
CallStack[cnt] = Pointer((PInteger(curFrame) + 4)^ - 4);                    
So wie du jetzt gepostet hast macht es auch Sinn:
user profile iconKainPlan hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
  St[Count]:= Pointer(PInteger(longint(CurrentFrame) + 4)^ - 4); //Hier steckt der wurm im verständniss                    
Es wird der Pointer CurrentFrame als Integerwert um 4 erhöht, dann dieser Integerwert als Pointer auf einen Integer interpretiert. Dann wird dieser neue Pointer dereferenziert und der dahintersteckende Integerwert um 4 reduziert. Und das ganze wird dann wieder als einen Pointer gecastet.

Im Speicher ist also hinter dem Pointer CurrentFrame (dessen Größe, da es ein Pointer ist, 4 Byte beträgt) ein Pointer auf einen Integerwert gespeichert. Dieser Integerwert, auf den der Pointer zeigt, wird um 4 reduziert und als Pointer gecastet zurückgegeben.

In C++ müsste das dementsprechend so aussehen:

Quelltext
1:
  St[Count] = (Pointer)(*((long*)((long)CurrentFrame + 4)) - 4);