C++-Prozedur als C-Callback-Funktion

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Leverator
Beiträge: 32
Registriert: Mo Jan 30, 2012 9:28 pm
Wohnort: ::1

C++-Prozedur als C-Callback-Funktion

Beitrag von Leverator » Fr Mai 14, 2021 7:36 am

Hallo zusammen,
ich habe hier ein kniffeliges Problemchen, an dem ich gestern den ganzen Tag herumgebastelt habe und eine Lösung gefunden habe, die aber eher unschön ist.

Ziel: Ich möchte ein vollständig objektorientiertes 3D-Progrämmchen basteln, das mir stereoskopische Bilder auf den 3D-Fernseher anzeigt.
Hierzu habe ich eine Klasse "window" definiert, die sich um das ganze Anzeige-Gedöns kümmern soll (MVC-Pattern halt).

Um mit der OpenGL-Hardware sprechen zu können, muss ich jedoch z.B. einen ErrorCallback als Funktionspointer an die genutzte Bibliothek übergeben.

Grobe Struktur ist also zur Zeit recht einfach:

Code: Alles auswählen

class window { ... Definitionsbums ... };
void window::ErrorCallback( int errorNo, const char* description ) { ... }
Das Problem besteht im Konstruktor der Klasse, wo der Funktionspointer in die Grafikbibliothek eingespeist werden muss.
Meine Lösung:

Code: Alles auswählen

window::window() {
    void (*fcnPtr)(int, const char*);
    fcnPtr = reinterpret_cast<void(*)(int, const char*)>(&window::ErrorCallback); // C-Funktionspointer auf C++-Prozedur (Yay!!) - aber mit Warning (Nay!!).  :)
    glfwSetErrorCallback( fcnPtr );
    
	std::cout << "Constructor window class" << std::endl;
    
}
Beim Kompilieren bekomme ich jedoch ein Warning ausgeworfen:

Code: Alles auswählen

g++ -c -std=c++17 -O2   -o window.o /home/torben/Development/eclipse-workspace/OpenGL-3D/window.cpp                                                                                                                                                                                       
/home/torben/Development/eclipse-workspace/OpenGL-3D/window.cpp: In Konstruktor »window::window()«:
/home/torben/Development/eclipse-workspace/OpenGL-3D/window.cpp:35:80: Warnung: Umwandlung von »void (window::*)(int, const char*)« nach »void (*)(int, const char*)« [-Wpmf-conversions]
   35 |     fcnPtr = reinterpret_cast<void(*)(int, const char*)>(&window::ErrorCallback); // C-Funktionspointer auf C++-Prozedur (Yay!!) - aber mit Warning. :)
      |                                                                                ^
g++ -lglfw -lGLEW -o OpenGL-3D OpenGL-3D.o window.o
Wer von Euch kann mir sagen, wie ich es so programmiere, dass die Pointerübergabe ohne Compiler-Warning funktioniert?

Viele Grüße,
Lev

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: C++-Prozedur als C-Callback-Funktion

Beitrag von Xin » Fr Mai 14, 2021 7:53 am

Moin Lev,

Das Definitionsbums wäre für ErrorCallback schon interessant. Du möchtest zwar super Objektorientiert laufen, nun ist der Grafikkartentreiber gar nicht so objektorientiert, wie Du Dir das wünschst: Es gibt im Callback nämlich kein "this". Die Funktion ErrorCallback muss static sein, es ist kann keine Methode sein.
Und wenn ich das hier lese:

Code: Alles auswählen

 fcnPtr = reinterpret_cast<void(*)(int, const char*)>(&window::ErrorCallback); 
ist sie das wohl nicht, wenn da eine Warninung kommt.
Dann ist die Warning berechtigt, denn das wird vermutlich knallen.

Die Methode hätte nämlich die Signatur void(*)(window *, int, char const *).

Wenn Du das objektorientiert halten willst, wird's komplizierter... nun hast Du aber vermutlich eh nur einen OpenGL-Kontext, weswegen die Kapselung in Objekte hier gar nicht so wichtig ist. Du kannst also ein Singleton als View-Implementierung für OpenGL anbieten. Hier kann in der Klasse quasi alles statisch sein, weil es ja auch alles nur einmal gibt. Entsprechend könnte eine ErrorCallback-Funktion auch auf alles zugreifen.
Was Du aber vermutlich auch nicht brauchst. Du musst da ja vermutlich einfach nur den empfangenden Text irgendwo ausgeben. Also mach ein static davor und sieh zu, dass Du das reinterpret_cast loswirst.

Ich hab jetzt spontan Lust auf Pizza, woran liegt das?
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Leverator
Beiträge: 32
Registriert: Mo Jan 30, 2012 9:28 pm
Wohnort: ::1

Re: C++-Prozedur als C-Callback-Funktion

Beitrag von Leverator » Fr Mai 14, 2021 1:39 pm

Hi Xin,
danke für Deine rasche Antwort.

Ich habe es nun geändert:

Code: Alles auswählen

class window {
private:
	GLFWwindow* win;
    int error;
    char my_foo[32];    // testdaten bounce-Funktion

public:
	window();
	~window();
	int info();
    static void ErrorCallback(int, const char*);
    int initGLFW();
    int loop();
};
und

Code: Alles auswählen

static void window::ErrorCallback(int error, const char* description) {
    std::cout << "Error Callback: " << std::hex << "0x" << error << "." << description << std::endl;
}
Und erhalte:

Code: Alles auswählen

g++ -c -std=c++17 -O2   -o window.o /home/torben/Development/eclipse-workspace/OpenGL-3D/window.cpp
/home/torben/Development/eclipse-workspace/OpenGL-3D/window.cpp:53:69: Fehler: Elementfunktion »static void window::ErrorCallback(int, const char*)« kann nicht deklariert werden, statische Bindung zu haben [-fpermissive]
   53 | static void window::ErrorCallback(int error, const char* description) {
      |                                                                     ^
Ich habe mich also von einem harmlosen Warning zum fetten Error hochgeschlafen... ;)

So richtig blicke ich es nicht...


Viele Grüße,
Lev

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: C++-Prozedur als C-Callback-Funktion

Beitrag von Xin » Fr Mai 14, 2021 2:35 pm

Lass in der .cpp-Datei das Static vor der Definition weg. Das static in der .cpp hätte eine andere Bedeutung, wenn es C wäre.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Leverator
Beiträge: 32
Registriert: Mo Jan 30, 2012 9:28 pm
Wohnort: ::1

Re: C++-Prozedur als C-Callback-Funktion

Beitrag von Leverator » Fr Mai 14, 2021 3:05 pm

Jawoll!!

Das war es. Danke!
It's compiling like a charme...

Ohne Warnings.

Antworten