Methode als SDL-Thread

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Methode als SDL-Thread

Beitrag von nufan » Mi Jun 17, 2009 4:29 pm

Ich wieder mal :)
Ich versuche jetzt schon ewig einen SDL-Thread aus einer Methode (public) zu erstellen. Doch der Compiler wehrt sich erbittert dagegen...

Ich nenne die Klasse jetzt nur zur Verallgemeinerung "CClass" und die Methode "methode". "t_methode" ist ein SDL_Thread* der die Methode ausführen soll.

Code: Alles auswählen

t_methode = SDL_CreateThread (&CClass::methode, NULL);
Diese Zeile steht im Konstruktor des Objekts.
Codeblocks gibt Folgendes aus:

Code: Alles auswählen

Fehler: »int (CClass::*)(void*)« kann nicht nach »int (*)(void*)« für Argument »1« nach »SDL_Thread* SDL_CreateThread(int (*)(void*), void*)« umgewandelt werden|
Ich sehe da kein Problem?! Die Methode hat die erforderliche

Code: Alles auswählen

int (*) (void *)
Signatur. Wobei das void *-Argument per default-Parameter auf NULL gesetzt wird (aber ohne das kommt der gleiche Fehler).

Schreibe ich den Klassennamen nicht dazu, bekomme ich diesen Fehler:

Code: Alles auswählen

Fehler: ISO-C++ verbietet das Ermitteln der Adresse einer nicht qualifizierten oder geklammerten nicht-statischen Elementfunktion, um einen Zeiger auf Elementfunktion zu erzeugen. Stattdessen »&CClass::methode« verwenden|
&CClass::methode ? Das ist doch genau was ich vorher gemacht habe...

Inzwischen hab ich schon alle Möglichkeiten ausprobiert: mit &, ohne &, mit Klassenname, ohne ihn, mit this, einen Zeiger erstellen und dessen Wert übergeben, usw. Nichts davon funktionierte. Ich hab ein funktionierendes Beispiel jedoch ist der Thread da eine ganz normale Funktion.

Jetzt natürlich die Frage: Was muss bei einer Methode anders sein? Hat das was mit dem implizit übergebenen this zu tun? static wäre unpraktisch, da ich in der Methode einige Membervariablen verwende. Wie mach ichs richtig?

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: Methode als SDL-Thread

Beitrag von Kerli » Mi Jun 17, 2009 5:09 pm

dani93 hat geschrieben:Jetzt natürlich die Frage: Was muss bei einer Methode anders sein? Hat das was mit dem implizit übergebenen this zu tun? static wäre unpraktisch, da ich in der Methode einige Membervariablen verwende. Wie mach ichs richtig?
Genau, das 'this' ist der Grund. Du brauchst nämlich den 'relativen' Zeiger von einer Klasse auf ihre Methode und noch den 'aboluten' Zeiger auf die Klasse. So direkt ist das nicht so einfach, aber ein schöner und einfacher Weg ist mit boost::bind bzw. allgemein irgendeiner Form von bind.

So schaut das zb. in einem Codeteil von mir aus:

Code: Alles auswählen

processing_thread_  ( boost::bind(&Manager::processEntries,this) );
processing_thread_ ist hier ein Boost Thread der hier eine Signatur 'void (*)(void)' erwartet. Mit bind wird eben auch noch der this-Zeiger "gebunden".
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Methode als SDL-Thread

Beitrag von nufan » Mi Jun 17, 2009 5:15 pm

Ich versuche das Problem mal von der anderen Seite anzugehen. Vielleicht schaffe ichs mit nur einem Thread. Ich kann nicht mal genau sagen obs mit 2 gehen würde, wollts nur mal ausprobieren ^^
Wenn ich wirklich keine andere Lösung finde, werde ich in "Algorithmen und Konzepte" posten ;)
Trotzdem danke für den Hinweis :)

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

Re: Methode als SDL-Thread

Beitrag von Xin » Do Jun 18, 2009 9:13 am

Erstelle eine statische Methode, der Du nicht NULL, sondern den this-zeiger übergibst - dafür ist der (void *) ja da. Ggfs. schreibst Du halt eine Struktur, die this und erforderlich Daten enthält.

In der statischen Funktion rufst Du static_cast< CClass *>( thisParameter )->method() auf.

Und gewöhn Dir ab vor Klassen "C" zu schreiben. Es ist so ziemlich alles eine Klasse, was Du programmierst und wenn alles mit C anfängt, dann trägt das C keine Information mehr und was keine Information trägt, solltest Du weglassen.

Wenn Du auf die ungarische Notation stehst, dann benutz Schlüsselwörter:

Code: Alles auswählen

class Class
{
  static int method()
  {
    return 0;
  }

  static int staticFunction( void * thisParameter )
  {
     return static_cast< class Class * >( thisParameter )->method();
  }
};
Den um die ungarische Notation müsstest Du sie eh komplett schreiben. Ansonsten frage ich Dich nämlich, warum Dein Code nur mit einer konstanten Klasse geht:

Code: Alles auswählen

typedef class Class const CClass;
Das meinst Du doch, oder? Weil C für Class wäre ja sinnfrei...
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.

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Methode als SDL-Thread

Beitrag von nufan » Do Jun 18, 2009 1:52 pm

Xin hat geschrieben:Erstelle eine statische Methode, der Du nicht NULL, sondern den this-zeiger übergibst - dafür ist der (void *) ja da. Ggfs. schreibst Du halt eine Struktur, die this und erforderlich Daten enthält.

In der statischen Funktion rufst Du static_cast< CClass *>( thisParameter )->method() auf.
Ich habs ohne zusätzlichen Thread geschafft. Hab mir etwas ähnliches wie eine Event-Schleife gebastelt. Zuerst wird geprüft ob Daten gesendet wurden. Wenn ja werden sie ausgegeben, wenn nein gehe ich zur Eingabe über. Mit SDL-Events kann ich das wahrscheinlich noch einfacher lösen.
Xin hat geschrieben:Und gewöhn Dir ab vor Klassen "C" zu schreiben. Es ist so ziemlich alles eine Klasse, was Du programmierst und wenn alles mit C anfängt, dann trägt das C keine Information mehr und was keine Information trägt, solltest Du weglassen.
Wurde mir so beigebracht und steht auch in einigen Büchern so. Bei "CClass" ist es zugegeben vollkommen sinnlos. Aber man wollte mir auch erzählen man soll vor jeder Membervariable "m_" schreiben...
Wenn man zusätzlich mit Strukturen arbeitet hilft es vielleicht ein bisschen. Ist eine Klasse in der alle Member public sind einer Struktur vorzuziehen?
Ich werds mir abgewöhnen :)

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

Re: Methode als SDL-Thread

Beitrag von Xin » Do Jun 18, 2009 2:07 pm

dani93 hat geschrieben:
Xin hat geschrieben:Und gewöhn Dir ab vor Klassen "C" zu schreiben. Es ist so ziemlich alles eine Klasse, was Du programmierst und wenn alles mit C anfängt, dann trägt das C keine Information mehr und was keine Information trägt, solltest Du weglassen.
Wurde mir so beigebracht und steht auch in einigen Büchern so. Bei "CClass" ist es zugegeben vollkommen sinnlos. Aber man wollte mir auch erzählen man soll vor jeder Membervariable "m_" schreiben...
Das mit m_ ist eine andere Baustelle, das hat sogar noch einen gewissen Sinn.
Das ist aber auch keine ungarische Notation mehr, denn ob Member oder nicht, ändert den Datentyp der Daten nicht.

Die CKlasse-Notation kommt aus alter Windows-Programmierung, daran hat sich Microsoft früher aufgegeilt. Die haben das aber inzwischen auch eingesehen, also lass Dir nix von Leuten über Technik erzählen, die noch träger reagieren als Microsoft. ^^
dani93 hat geschrieben:Wenn man zusätzlich mit Strukturen arbeitet hilft es vielleicht ein bisschen. Ist eine Klasse in der alle Member public sind einer Struktur vorzuziehen?
Die sind gleichwertig.

Bei Structs sind die Member per Default public, bis Du was anderes sagst - bei Class sind die Member per default private, bis Du was anderes sagst.
Das war's schon.
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.

Antworten