Page 1 of 1

C++ and pthreads

Posted: Tue Jan 09, 2007 6:02 pm
by Alboin
Hello!
I have been trying to create multiple threads in a C++ program I am developing. Moreover, I plan to create a nice class to enclose pthreads. However, when trying to pass a member function (virtual, non-virtual) to pthread_create I always get this error:

Code: Select all

mtkWindow.cc: In member function `void* mtkWindow::run()':
mtkWindow.cc:93: error: argument of type `void*(mtkWindow::)(void*)' does not
   match `void*(*)(void*)'
A cut down version of the class:

Code: Select all

class mtkWindow : public mtkWidget {
	private:
		pthread_t thread;			
		void *thread_main(void *arg);
	public:
		void *run();
		void main() {
			pthread_join(thread, NULL);
		}
};
And the Code:

Code: Select all

void *mtkWindow::run()
{
	pthread_create(&thread, NULL, thread_main, (void*)this);
}

void *mtkWindow::thread_main(void *arg)
{
	for(;;) {
		///Do whatever...
	}
}
I was reading about templates to solve the problem, but I think I am still stuck with it when I get down to pthread_create. I have also tried casting it to anything I could think of with no results :cry: ... Thanks!

Posted: Tue Jan 09, 2007 9:09 pm
by Alboin
Hello,
I think I found a solution: instead of directly passing the member function to pthread_create, pass a extern "C" declared function to it with the this pointer as an argument. Then, in the extern "C" function call this->thread_main(). Thanks! (Sorry for posting a dud topic... :roll:)

Posted: Thu Jan 11, 2007 12:06 pm
by Candy
The difference is that you're passing a member function pointer instead of a function pointer. The first requires the implicit "this" pointer, the second forbids it. To call the first requires an object to call it on. You can also make a static member function (that doesn't use a this pointer) instead. Your function doesn't even have to be extern "C", but just can't be in a class.

Code: Select all

class Thread {
    pthread_t thr;
    void start() {
        pthread_create(&thr, 0, &Thread::doRun, this);
    }
    static void *doRun(void *obj) {
        Thread *to = (Thread *)obj;
        obj->run();
    }
    virtual void run() = 0;
};

Posted: Thu Jan 11, 2007 6:32 pm
by Alboin
Candy wrote:The difference is that you're passing a member function pointer instead of a function pointer. The first requires the implicit "this" pointer, the second forbids it. To call the first requires an object to call it on. You can also make a static member function (that doesn't use a this pointer) instead. Your function doesn't even have to be extern "C", but just can't be in a class.

Code: Select all

class Thread {
    pthread_t thr;
    void start() {
        pthread_create(&thr, 0, &Thread::doRun, this);
    }
    static void *doRun(void *obj) {
        Thread *to = (Thread *)obj;
        obj->run();
    }
    virtual void run() = 0;
};
... :shock: Really? I never realized that a member function and a normal function were so different.... Hmmm..... Maybe I should read up on my C++......