Function Pointer

Übersicht BlitzMax, BlitzMax NG FAQs und Tutorials

Neue Antwort erstellen

Jolinah

Betreff: Function Pointer

BeitragDo, Mai 19, 2005 0:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich dachte ich schreibe noch eine "kleine" Ergänzung zum Pointer-Tutorial.
Function Pointer wurden da noch nicht behandelt.

Typesafe
Zu erwähnen ist dass die Function Pointer in BMax typesafe sind, das heisst sie verhalten sich ähnlich wie Referenzen. Ein Int Ptr kann auch nicht plötzlich auf einen Float zeigen, sondern immer nur auf einen Int.


Deklaration
Die Deklaration von Function Pointern verhält sich etwas anders als bei normalen Pointern, hier ein Beispiel:

Code: [AUSKLAPPEN]
Local funcPtr()


Damit hat man bereits seinen ersten Function Pointer erstellt. Dieser Pointer nimmt allerdings nur Adressen von Funktionen an die den selben Rückgabetyp und die selben Parameter haben, weil die Pointer ja typesafe sind. In diesem Fall Funktionen mit Integer als Rückgabetyp und keinem Parameter.


Zuweisung
Wie bei den normalen Pointern speichert ein Function Pointer auch nur die Adresse, die Adresse einer Funktion. Die Funktion die dem Pointer zugewiesen wurde kann dann ausgeführt werden über den Namen des Function Pointers. Dies geschieht wie beim Aufruf einer normalen Funktion durch springen an die Funktions-Speicheradresse. Nach beenden der Funktion wird wieder an den Ursprungspunkt gesprungen.

Um dem Zeiger eine Funktion zuweisen zu können müssen wir erstmal eine erstellen, oder gleich mehrere:

Code: [AUSKLAPPEN]
Function func1()
End Function

Function func2()
End Function


Nun können wir dem Function Pointer entweder func1 oder func2 zuordnen:

Code: [AUSKLAPPEN]
funcPtr = func1


Zu beachten ist dabei dass bei der Zuweisung keinerlei Klammern nötig sind, nur den reinen Namen der Funktion.


Aufrufen / Ausführen der referenzierten Funktion
Wir können nun die Funktion auf die funcPtr zeigt ausführen:

Code: [AUSKLAPPEN]
funcPtr()


In Wirklichkeit wird nun func1 ausgeführt. Hiermit sollte der Vorteil der Function Pointer schon klar sein. Man kann in funcPtr immer andere Funktionen referenzieren aber man ruft sie trotzdem immer gleich auf.


Kleines Beispiel

Code: [AUSKLAPPEN]
Global ki_state() 'unser func ptr
Global Leben = 100
Global getroffen = True

'Normalzustand der KI
Function Idle()
  If getroffen then Leben = Leben - 1
 
  Print "Leben: " + Leben

  If Leben <= 0 then ki_state = Tot  'func ptr zeigt nun auf Tot
  return 1
End Function

'KI Zustand: Tot
Function Tot()
  Print "Ich bin tot"
  return 0
End Function

ki_state = Idle 'Anfangs zeigt func ptr auf Idle, am Ende auf Tot

Local state:Int = 1

While state > 0
  state = ki_state()  'egal welcher KI Zustand, Funktion wird ausgeführt.
End While


Hier ist der Func. Pointer Global und wird direkt in der Idle Funktion neu zugewiesen sobald Leben = 0 ist. Dies hat zur Folge dass dann nicht mehr Idle() sondern Tot() ausgeführt wird. Tot() gibt 0 zurück weshalb sich das Programm dann beendet.


Function Pointer in Types
Es ist auch möglich die Function Pointer in Types zu verwenden:

Code: [AUSKLAPPEN]
Type bla

  Field funcPtr()

  Function blubb()
  End Function

  Method New()
    funcPtr = bla.blubb
  End Method

End Type


Einzige Einschränkung ist in BMax das man nicht eine Methode einer Instanz referenzieren kann. Statische Funktionen jedoch schon.

Function Pointer als Funktionsparameter übergeben
Man kann wie jeden Type und Pointer auch Function Pointer als Parameter einer Funktion übergeben:

Code: [AUSKLAPPEN]
Function tu_was( funcPtr() )
  funcPtr()  'Die Funktion die im Pointer referenziert ist wird ausgeführt.
End Function

Function tu_was_anderes()
  Print "blubb"
End Function

Local myfuncPtr() = tu_was_anderes

tu_was( myfuncPtr ) 'tu_was wird ausgeführt, mit übergabe des Pointers.


Hier möchte ich auch nicht weiter drauf eingehen, sollte ja nun klar sein.

Fehler vermeiden
Ein Func Pointer kann ja auch mal auf nichts zeigen. In diesem Fall enthält er den Wert Null. Man sollte bevor man die referenzierte Funktion ausführt besser immer prüfen ob der Func Pointer auch auf etwas Zeigt (<> Null). Ansonsten kommt es zu Memory Exceptions.


Schlusswort
Ich habe jetzt immer Standard Funktionen verwendet. Man kann natürlich genausogut jede andere Funktion verwenden. Im Hinterkopf muss man jedoch daran denken das die Func Pointer typesafe sind.

Code: [AUSKLAPPEN]
Function tu_was:MyType(a:Int, b:Float)
  return null
End Function

Local funcPtr:MyType(x:Int, y:Float)

funcPtr = tu_was

funcPtr(10, 20.0)
 

Ava

Gast

BeitragDi, Aug 30, 2005 14:48
Antworten mit Zitat
Um das hier mal zu würdigen: Danke für Deinen Beitrag, er hat mir SEHR geholfen! Smile

Lieben Gruss,
+ Ava +

Fetze

BeitragDi, Sep 13, 2005 21:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Kann ich auch auf Methoden verweisen? Ich hab zwar die Suchenfunktion verwendet, bin aber nicht wirklich fündig geworden.

Suco-X

Betreff: .......

BeitragDi, Sep 13, 2005 21:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Dann teste es doch mal kurz...
Mfg Suco
Intel Core 2 Quad Q8300, 4× 2500 MHz, 4096 MB DDR2-Ram, GeForce 9600GT 512 MB

Fetze

BeitragDi, Sep 13, 2005 22:30
Antworten mit Zitat
Benutzer-Profile anzeigen
....du meinst, ich soll einfach Objektverweis.Methode() schreiben?
Hm, okay. Sorry, da bin ich erst gar nicht drauf gekommen. Dachte mir, das könne gar nicht so einfach sein oO

Fetze

BeitragMi, Sep 14, 2005 21:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich bekomme hier seltsamerweise folgende Fehlermeldung beim Kompilieren:

Zitat:

Unable to convert from 'Byte(Int,Int,Int,Int)' to 'Byte(Int,Int,Int,Int)'


...wtf?

Suco-X

Betreff: .....

BeitragMi, Sep 14, 2005 22:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Dann gehts wohl nicht Wink
Habs auch getestet, geht wohl nur mit Funktionen.
Mfg Suco
Intel Core 2 Quad Q8300, 4× 2500 MHz, 4096 MB DDR2-Ram, GeForce 9600GT 512 MB

hamZta

Administrator

BeitragDo, Sep 15, 2005 13:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Guckst du hier:

Zitat:
Einzige Einschränkung ist in BMax das man nicht eine Methode einer Instanz referenzieren kann. Statische Funktionen jedoch schon.


Steht doch im Tutorial.
Blog.

Fetze

BeitragDo, Sep 15, 2005 16:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Hm, okay, dann werd ich das wohl über nen Umweg machen.

Pointer --Aufruf--> Function --direkte weiterleitung--> Methode

Wenn ich der Function einfach einen Parameter übergebe, der das Objekt der aufzurufenden Methode enthält, sollte das kein Problem sein.

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG FAQs und Tutorials

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group