Seite 1 von 2

Abfrage PB-interner Variablen ... aber WIE ???

Verfasst: 02.05.2006 13:12
von The Rookie
Hallo zusamen, ...

in der Library-SDK habe ich ja bereits Informationen zu PB-internen Variablen wie z.B.

Code: Alles auswählen

  _PB_2DDrawing_CurrentDC    ; OS Current DC (HDC)
  _PB_2DDrawing_CurrentColor ; Current RGB 24 color
  _PB_2DDrawing_CurrentMode  ; Current drawing mode (Set by DrawingMode())
  _PB_2DDrawing_Brush        ; Current brush (for flood fill), set by FrontColor() (HBRUSH)
  _PB_2DDrawing_Pen          ; Current pen (for outline color), set by FrontColor() (HPEN)
gefunden.

In dem tollen CreateGadget-Code von hallodri und ts-soft habe ich auch schon mal Beispiele gefunden dass man damit arbeiten kann.

[EDIT:] Habe hallodris Namen korrigiert. Ehre, wem Ehre gebührt !!! ;)

Nur: Ich habe nicht ganz verstanden - WIE !?!

Geht dies nur mit Assembler Befehlen und wenn ja, was bedeutet z.B.

Code: Alles auswählen

  !EXTRN _PB_Object_GetThreadMemory@4
  !EXTRN _PB_Gadget_Globals
  !MOV   Eax,[_PB_Gadget_Globals]
  !push  eax
  !call  _PB_Object_GetThreadMemory@4
  !MOV   Eax,[Eax]
1. !MOV ist wohl relativ klar
2. !push wird wohl zum pushen auf den Stack sein
3. bei !call bin ich mir nicht so ganz sicher, vermutlich ja zurückholen von Stack
4. aber was genau macht !EXTRN und
5. wo genau liegt der Unterschied zwischen Eax und [Eax]
6. und was genau ist Eax nochmal (war das nicht irgenwie der Rückgabewert .... aber wohin)?


So mal als Beispiel:

Ich würde gerne eine Procedur schreiben, die mir ausgibt ob ein Screen geöffnet ist oder nicht.
Eine solche Funktion hat PB ja meines Wissens nach (momentan noch) nicht.

Hierzu müsste ich ja vermutlich _PB_DirectX_CurrentDC oder z.B. auch einfach _PB_DirectX_ScreenWidth abfragen.
Wie müsste dann z.B. eine solche Prozedur aussehen?
Meine eigenen Versuche wie z.B.

Code: Alles auswählen

Procedure IsScreen() 
  !EXTRN _PB_DirectX_ScreenWidth
  !MOV   Eax,[_PB_DirectX_ScreenWidth]
  !MOV   Eax,[Eax]
  ProcedureReturn
EndProcedure 
brachten bisher immer nur einen POLINK-Error : 1 unresolved external(s).

Vielen Dank schon mal und schöne Grüße,
The Rookie.

Re: Abfrage PB-interner Variablen ... aber WIE ???

Verfasst: 02.05.2006 13:21
von Laurin
1. MOV A, B kopiert den Inhalt von B nach A.
2. Genau. PUSH A kopiert den Inhalt von A auf den Stack.
3. CALL ruft eine Funktion auf. Diese Funktion aber kann z.B. EAX verändern, damit du einen Rückgabewert hast.
4. Meines Wissens nach sorgt der Befehl dafür, dass eine Funktion auch nach außen hin sichtbar wird, so dass man z.B. von einem anderen Programm darauf zugreifen kann. Nützlich z.B. bei DLLs, wo man üblicherweise von außen auf deren Funktionen zugreift..
5. EAX ist eines der Prozessorregister. Es ist 32 Bit groß. Damit rechnet die CPU. Es ist sozusagen eine Hardware-Variable. Es gibt noch mehr Register, z.B EBX, ECX, usw. Jedes Register hat eine besondere Funktion, man muss also aufpassen, was man da reinschreibt.

Greetz Laurin

Verfasst: 02.05.2006 13:40
von Karl
Das

Code: Alles auswählen

 MOV EAX, [EAX]
sieht aus wie registerindirekte Adressierung - heißt kopiere den Inhalt, der an der Speicherzelle steht, die gerade durch EAX adressiert wird, auf EAX.

Gruß Karl

Re: Abfrage PB-interner Variablen ... aber WIE ???

Verfasst: 02.05.2006 13:41
von freedimension
Laurin hat geschrieben:4. Meines Wissens nach sorgt der Befehl dafür, dass eine Funktion auch nach außen hin sichtbar wird, so dass man z.B. von einem anderen Programm darauf zugreifen kann. Nützlich z.B. bei DLLs, wo man üblicherweise von außen auf deren Funktionen zugreift..
EXTRN deklariert Variablen oder Funktionen als externe und noch nicht näher definiert. Dies wird gemacht, damit der Compiler weiß, dass diese erst beim Linken hinzukommen werden, der Compiler setzt solange einfach eine Art Platzhalter ein.
Das ist genau das, was hier benötigt wird, Variablen wie z.B. _PB_2DDrawing_CurrentDC sind in externen Bibliotheken definiert, davon weiß der aktuelle Code aber nichts, da diese erst zum Zeitpunkt des Linkens hinzugefügt werden.

Re: Abfrage PB-interner Variablen ... aber WIE ???

Verfasst: 02.05.2006 14:22
von mueckerich
The Rookie hat geschrieben:Hallo zusamen, ...

In dem tollen CreateGadget-Code von mueckerich und ts-soft habe ich auch schon mal Beispiele gefunden dass man damit arbeiten kann.
Sorry, aber das sind fremde Lorbeeren, mit dem CreateGadget habe ich (leider) nichts zu tun. Die Ehre gebührt allein Thomas. :allright:

Re: Abfrage PB-interner Variablen ... aber WIE ???

Verfasst: 02.05.2006 15:56
von ts-soft
mueckerich hat geschrieben:
The Rookie hat geschrieben:Hallo zusamen, ...

In dem tollen CreateGadget-Code von mueckerich und ts-soft habe ich auch schon mal Beispiele gefunden dass man damit arbeiten kann.
Sorry, aber das sind fremde Lorbeeren, mit dem CreateGadget habe ich (leider) nichts zu tun. Die Ehre gebührt allein Thomas. :allright:
Bild
hallodri heißt dieser Mithelfer :D

Re: Abfrage PB-interner Variablen ... aber WIE ???

Verfasst: 02.05.2006 18:23
von The Rookie
@hallodri
uhhps, ... sorry. Wollte Deine Leistung nicht unter den Tisch kehren (hab's auch schon korrigiert). :)
Aber wie heisst es nochmal: Wer im Source richtig lesen kann ist klar im Vorteil (oder so ähnlich)? :allright:
freedimension hat geschrieben:EXTRN deklariert Variablen oder Funktionen als externe und noch nicht näher definiert. Dies wird gemacht, damit der Compiler weiß, dass diese erst beim Linken hinzukommen werden, der Compiler setzt solange einfach eine Art Platzhalter ein.
Das ist genau das, was hier benötigt wird, Variablen wie z.B. _PB_2DDrawing_CurrentDC sind in externen Bibliotheken definiert, davon weiß der aktuelle Code aber nichts, da diese erst zum Zeitpunkt des Linkens hinzugefügt werden.
@freedimension,...
sowas ähnliches hatte ich mir schon gedacht - nur scheint der Linker die Variable (z.B. _PB_DirectX_ScreenWidth) bei mir nicht zu finden.

Fehlt da noch was? Muss ich noch irgendwas includen?
Müsste ich erst die Library öffnen (per OpenLibrary)?
:roll:

Im CreateGadget Code sind ja (vermutlich für sowas) 2 Prototypes deklariert (die ja laut Doku scheinbar einen Openlibrary ersetzen können).
Aber der Hintergrund und die Funktionsweise von Prototypes habe ich noch nicht so ganz verstanden. :|

Verfasst: 02.05.2006 23:06
von freedimension
Es sollte schon mindestens eine Funktion der entsprechenden Library aufgerufen worden sein, ansonsten wird diese auch nicht verlinkt und der Linker findet die externen Variablen nicht. In welchem Kontext rufst du das ganze auf?

Verfasst: 02.05.2006 23:32
von ts-soft
Hier mal so ein Dummyaufruf aus CreateGadget:

Code: Alles auswählen

Procedure GetGadgetParent() 
  !EXTRN _PB_Object_GetThreadMemory@4
  !EXTRN _PB_Gadget_Globals
  !MOV   Eax,[_PB_Gadget_Globals]
  !push  eax
  !call  _PB_Object_GetThreadMemory@4
  !MOV   Eax,[Eax]
  ProcedureReturn
  CreateGadgetList(0) ; Dummyaufruf
EndProcedure 
Hier wird sichergestellt, das CreateGadgetList mit hinzugelinkt wird.

Verfasst: 02.05.2006 23:59
von The Rookie
ts-soft hat geschrieben:Hier mal so ein Dummyaufruf aus CreateGadget:

Code: Alles auswählen

Procedure GetGadgetParent() 
  !EXTRN _PB_Object_GetThreadMemory@4
  !EXTRN _PB_Gadget_Globals
  !MOV   Eax,[_PB_Gadget_Globals]
  !push  eax
  !call  _PB_Object_GetThreadMemory@4
  !MOV   Eax,[Eax]
  ProcedureReturn
  CreateGadgetList(0) ; Dummyaufruf   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
EndProcedure 
Hier wird sichergestellt, das CreateGadgetList mit hinzugelinkt wird.
Ach, ... DAFÜR war der !!!

Ich hatte mich schon gewundert wozu der denn sein soll (da er ja nie ausgeführt wird) und hatte den natürlich bei meinen Versuchen sofort rausgeschmissen !!! :lol:

Im Originalsource stand ja der Hinweis zu einem 'Dummyaufruf' nicht dabei.
Macht aber natürlich vollkommen Sinn. ;)

Vielen Dank an Euch ... ich schätze mal, dass ich jetzt weiter komme. :allright:
Grüße, The Rookie.


[Nachtrag:] Doch noch 'ne kleine Frage:

Wie bekomme ich denn nun am einfachsten den Wert einer PB-internen Variable in eine 'echte' Variable - soll heissen - wie kann ich denn nun darauf zugreifen?

Muss ich das per ASM innerhalb einer Prozedur machen (da Eax ja soweit ich das verstanden habe als Procedur-Returnwert übergeben wird) oder kann man das auch irgendwie direkt im 'laufenden' Code machen?