Advertisement

Thread from Class Member Function?

Started by August 13, 2000 10:35 PM
6 comments, last by Balrin 24 years, 4 months ago
Has anybody ever created a thread off a function from a classes member function? I have created many threads off of standard functions with no problem using both _beginthread and CreateThread, however I can''t get either to compile when passing a classes function to the thread. If I pull the function outside the class it compiles(of course it now can''t find the member functions it needs...) Has anybody ran into this and know a fix? Thanks, Balrin
Hi,

I ran into that problem - my solution was to create a normal thread function that I then passed the ''this'' pointer to the object to.
The thread function then called a class member function to do the actual work.
A bit ugly as you need a seperate thread function. However you can create the thread within the constructor and control it from within the object.
Any better ways?

-Devore
Advertisement
Balrin:

what is the error you are getting?
Most of the time these problems have to do with forgetting the implicit this pointer of methods. Function prototypes no longer match and voila .

Jaap
____________________________Mmmm, I''ll have to think of one.
I''ve got a very similar problem: I''m using the UnRAR.dll delivered with the famous WinRAR archiver.

This works fine:
int __cdecl ProcessProc(unsigned char *addr, int size) {  // Do something}void ExtractSomething(void) {  UnRar->rarSetProcessDataProc(handle, ProcessProc);}


But if I move the ProcessProc() function into a class, like
class CUnRarFile {  int __cdecl ProcessProc(unsigned char *addr, int size);  void ExtractSomething(void);};int __cdecl CUnRarFile:rocessProc(unsigned char *addr, int size) {  // Do something}void CUnRarFile::ExtractSomething(void) {  UnRar->rarSetProcessDataProc(handle, ProcessProc);}


I''m getting the following error:

error C2664: ''void (void *,int (__cdecl *)(unsigned char *,int))'' : Conversion of parameter 2 from '''' to ''int (__cdecl *)(unsigned char *,int)'' not possible

The entire thing would work if I''d use only the function adress, like

class CUnRarFile {  int __cdecl RealProcessProc(unsigned char *addr, int size);  int (__cdecl *ProcessProc)(unsigned char *addr, int size);  void ExtractSomething(void);};int __cdecl CUnRarFile::RealProcessProc(unsigned char *addr, int size) {  // Do something}void CUnRarFile::ExtractSomething(void) {  ProcessProc = RealProcessProc;  UnRar->rarSetProcessDataProc(handle, ProcessProc);}


Of course, the bold line is needed to let ProcessProc point to the RealProcessProc() function -- but how should I be, the same error then happens in that line.

I thought about
class CUnRarFile {  friend int __cdecl ProcessProc(unsigned char *addr, int size);  void ExtractSomething(void);};static CUnRarFile *Self;static int __cdecl ProcessProc(unsigned char *addr, int size) {  // Do something}void CUnRarFile::ExtractSomething(void) {  Self = this;  UnRar->rarSetProcessDataProc(handle, ProcessProc);}


This way, the ProcessProc() function would have access to the class members, but the entire thing would not be thread-safe. While thread a is running ProcessProc(), thread b could change ''Self'' and both ProcessProc()s from thread a and b would work with the data of thread b. ...or, simply said, total chaos.

If thread safety isn''t too important for you, this solution would work. If anyone has a better idea, please post it. I really need a thread safe method!

-Markus-
Professional C++ and .NET developer trying to break into indie game development.
Follow my progress: http://blog.nuclex-games.com/ or Twitter - Topics: Ogre3D, Blender, game architecture tips & code snippets.
The error I''m gettins is as follows:

error C2664: ''_beginthread'' : cannot convert parameter 1 from ''void (void *)'' to ''void (__cdecl *)(void *)''

However pull the function outside the class and no compile error... If there is a quick fix to this let me know.

I''m going to try Devore suggestion for now of passing a pointer to the class and see what happens.
You can''t use a regular member function as a the entry point for a thread because regular member functions have a hidden "this" pointer that the OS doesn''t know about.

What you need to do is to use a static member function as the entry point and pass the this pointer to it.

e.g.

    #include <windows.h>#include <stdio.h>#include <process.h>class Foo{private:    static void __cdecl ThreadMain(void *_this)  {((Foo *) _this)->ThreadMain();}    void ThreadMain()    {printf("Hello world");}public:    void StartThread()   {_beginthread(ThreadMain, 0, this);}};void main(){    Foo f;    f.StartThread();    Sleep(1000);}    


-Mike

Advertisement
Whoa, very tricky. Let me see if I got this correct. You are creating an overloaded member function which is passed for the thread which in turn calls the other version of the function to complete the task...
I wouldn't have thought of that

Edited by - Balrin on August 14, 2000 6:38:05 PM
Yes, this solution is similar to my ''Self'' variable, which is just passed as a parameter that would make the function thread safe.
The only problem is, that I''m bound to the poor programming of UnRAR.dll (ever looked at the free UnRar-tool sourcecode ? Oh my God!).

The extraction function requires the adress of a function of type
int __cdecl Function(unsigned char *addr, int size)
then (while extracting) it will call back the given function with variable sized chunks of data extracted.

Said shortly, I cannot add the ''_this'' parameter because I do not have access to the sourcecode of UnRAR.dll.

(yeah, if the function looked like int __cdecl Function
(unsigned char *addr, int size, void *userarg)
, as do all MS DX callback functions everything would be fine...)

Does anyone have a solution for this particular problem ?
Perhaps disassemble UnRAR.dll and add the required parameter ?!

-Markus-
Professional C++ and .NET developer trying to break into indie game development.
Follow my progress: http://blog.nuclex-games.com/ or Twitter - Topics: Ogre3D, Blender, game architecture tips & code snippets.

This topic is closed to new replies.

Advertisement