Generell geht es hier um den ESP8266, aber die Frage lässt sich denke
ich allgemein auf C bzw. C++ übertragen.
Ich habe eine Klasse Wifi die eine Methode hat, mit der man das
Wifi-Netzwerk scannen kann. Sobald die umgebenen Netzwerke gescannt
worden sind, wird eine Callback-Funktion in Form eines Funktionspointers
aufgerufen, der der Methode zuvor übergeben wurde.
D.h. in meiner main-Datei ergibt sich folgendes:
Die mit den 3 Fragezeichen markierte Zeile habe ich bereits in drei
Varianten ausprobiert, die alle einwandfrei kompiliert haben aber den
Controller innerhalb von einer Sekunde (eben sobald die Methode
aufgerufen wird) zum Absturzt bringen. Die drei Varianten sind:
1
wifi_station_scan(&sc,scan_done_cb);
2
wifi_station_scan(&sc,*scan_done_cb);
3
wifi_station_scan(&sc,&(*scan_done_cb));
Wie genau übergebe ich den Funktionspointer nun korrekt?
Dr. Sommer schrieb:> Was ist request_scan ?
Achso, ups. Das sollte eigentlich scan_wifi_networks heißen, sry.
Dr. Sommer schrieb:> Es wäre aber hilfreich, die Definition von wifi_station_scan zu sehen.
Anbei die Definition aus der Doku.
Max M. schrieb:> Wie genau übergebe ich den Funktionspointer nun korrekt?
Die erste Variante, also einfach den Zeiger benennen (scan_done_cb).
Wenn dabei etwas abstürzt, ist was anderes foul.
Schöner schreibt sich der Typen-Krams natürlich mit einem typedef, das
sieht weniger verwirrend aus.
Eine globale Funktion würde ich nach Möglichkeit nicht genauso benennen
wie einen formalen Parameter.
A. K. schrieb:> Allgemein: Man sollte lieber nicht davon ausgehen, dass ein void * immer> auch einen function pointer aufnehmen kann.
Davon darf man auch nicht ausgehen – aber ich sehe hier nicht, dass er
das machen würde.
Wenn man einen "generischen" Funktionszeiger braucht, kann man
1
typedefvoid(*generic_func_p)(void);
benutzen und von / nach diesem casten. Alle Funktionszeiger sind per
definitionem per Cast ineinander überführbar, aber Casts zwischen
Funktions- und Objektzeiger sind nicht statthaft. (Einfaches Beispiel,
wo sowas total schief geht, ist ein AVR mit 256 KiB: der Funktionszeiger
ist dort 24 Bit breit, der Objektzeiger nur 16 Bit.)
Schöner ist es natürlich immer ohne Cast; das ist hier aber der Fall.
Max M. schrieb:> Hm, klappt leider auch nicht:
Ja, ist auch kein Unterschied, nur schöner. Glaube nicht dass es am
Funktionspointer liegt. Wenn du die Callback-Funktion komplett leer
machst geht's bestimmt...
Dr. Sommer schrieb:> Wenn du die Callback-Funktion komplett leer> machst geht's bestimmt...
:D
Woher weißt du das?
P.S. Jetzt funktioniert es auch, hab mir die Doku nochmal angesehen und
bemerkt, dass der Status überprüft wird.
Das hatte ich vergessen.
Die Callback-Funktion sieht so aus: