Ein Problem mit _BeginThread's Parameterliste

Hallo Tutorialisten,

ich habe eine Fensteranwendung(mit VC2008Express und winXP SP2) geschrieben, bzw. bin gerade dabei, in der ich in einem Thread berechnungen durchführen möchte, und sie in einer Textbox anzeigen lasse.
Der Thread(maThread) ist eine Methode.

Code:
class threader
{
private:
	int params;
public:
	threader() :
		params(0)
	{}

	void setP(int& wert)
	{
		params = wert;
	}
	int getP()
	{
		return params;
	}
	void maThread(void* pParams)
	{
		int Params = (int)pParams;

		while(Params != 0)
		{
			for(;Params != 0; Params--)
			{
				machwas mit Params;
				setP(Params);
			}
		}
	}
};

keine Probleme bis hier.
So: jetzt habe ich einen Button, nach dessen betätigung der Thread gestartet werden soll.

Code:
System::Void button1_Click(System::Object^  sender, System::EventArgs^  e)
 {
	 if(theThread == NULL)
	 {
		 theThread = new threader;
	 }
	 static int x(0);
	 x++;
	 _beginthread(theThread->maThread, 0, (void *)x);
 }

Allerdings sagt mir mein Compiler :
Fehler 115 error C3867: "threader::maThread": Dem Funktionsaufruf fehlt die Argumentliste. Verwenden Sie "&threader::maThread", um einen Zeiger auf den Member zu erstellen.

Was mich an dieser Stelle verwundert ist, dass ich den Thread schon am laufen hatte, bevor er als Methode der "threader" Klasse implementiert wurde, wo ich ihn so
_beginthread(maThread, 0, (void *)x);
problemlos starten konnte.

Bitte um Hilfe,

Vielen Dank schonmal im Voraus, random.
 
Hi.

Du kannst _beginthread keine Methode einer Klasse übergeben. Zu einer Methode gehört immer eine Instanz einer Klasse welche automatisch als erster Parameter übergeben wird.

Du könntest die Methode der Klasse höchstens als static deklarieren. Dann macht aber die ganze Klasse eigentlich nur wenig Sinn.

Warum verwendest du nicht die .NET Thread Klasse? Du verwendest doch eh schon C++/CLI...

Gruß
 
Vielen Dank schonmal,
Du kannst _beginthread keine Methode einer Klasse übergeben. Zu einer Methode gehört immer eine Instanz einer Klasse welche automatisch als erster Parameter übergeben wird.
Kann ich dann mit Funktionspointern arbeiten?
Du könntest die Methode der Klasse höchstens als static deklarieren. Dann macht aber die ganze Klasse eigentlich nur wenig Sinn.
Es geht mir hauptsächlich darum einen Thread in eine GUI zu packen...
Warum verwendest du nicht die .NET Thread Klasse? Du verwendest doch eh schon C++/CLI...
... ich habe ehrlich gesagt erst heute begonnen mich damit auseinanderzusetzen :rolleyes: außerdem ist es das erste mal das ich Threads & GUI programmiere..
Welche Möglichkeiten gibt es, das sauber aufzuziehen, ohne dabei über externe Libraries wie MFC oder QT zu gehen?(oder verwechsel ich da grad etwas?)

Gruß zurück ;)
 
Kann ich dann mit Funktionspointern arbeiten?
Ja, natürlich kannst du Zeiger auf normale Funktionen verwenden.
... ich habe ehrlich gesagt erst heute begonnen mich damit auseinanderzusetzen :rolleyes: außerdem ist es das erste mal das ich Threads & GUI programmiere..
Welche Möglichkeiten gibt es, das sauber aufzuziehen, ohne dabei über externe Libraries wie MFC oder QT zu gehen?(oder verwechsel ich da grad etwas?)
Wenn du .NET verwendest, könntest du einen BackgroundWorker (System::ComponentModel::BackgroundWorker) verwenden. Den kannst du einfach im
Designer auf dein Formular ziehen und dessen Eigenschaften anpassen.

Dazu mußt du nur die EventHandler konfigurieren - d.h. den DoWork EventHandler festlegen. Um den Worker zu starten mußt du nur die RunWorkerAsync Methode des Workers aufrufen.

Gruß
 
C++:
template<typename object_type, typename function_type>
struct thread_function
{
	typedef object_type object_t;
	typedef function_type function_t;

    	typedef struct parameters
	{
		object_t* obj;
		function_t func;
		parameters(obect_t& object. function_t function)
			: obj(object), func(function)
		{}
	} parameter_t;

    	static void entry(void* ptr_param)
	{
		parameter_t* param(static_cast<parameters*>(ptr_param));
		((param->obj)->*(param->func))();
		delete param;
	}
};

C++:
class foo
{
	int m_bar;

public:
	void run() { std::clog << m_bar++ << std::endl; std::clog << m_bar; }
};

typedef thread_function<foo, void (foo::*)()> foo_entry_t;

int main()
{
    foo instance;
    ::_beginthread(foo_entry_t::entry, 0, new foo_entry_t::parameter_t(instance, &foo::run));
}
nur aufpassen, das du jetzt nicht mit instance rumspielst ;)

PS: Das ist nur ein spontaner Einfall und kann sein das es so nicht auf Anhieb funktioniert, aber das Prinzip sollte klar sein ;)
 
Vielen Dank auch für deine Hilfe DevDevil,

aehm soo klar ist es leider nicht ;D

aber ich hock mich morgen weiter dran und gebe bescheid, welche Klarheiten noch beseitigt werden können :p

Gruß, random.
 
Zurück