2

Recently I've been designing a Thread class library, I've made a Thread abstract class like the following:

class Thread {
public:
    run() { /*start the thread*/ }
    kill() { /*stop the thread*/ }
protected:
    virtual int doOperation(unsigned int, void *) = 0;
};

Real thread classes would inherit this abstract class and implement doOperation method in its own logic, something similar to Strategy Pattern.

The problem is that I'm relying on a C back-end library which defines running the thread in the following function:

int startThread(char* name, (int)(*)(unsigned int, void*), int, int, int, void*);

As you can see; the second parameter is a function pointer to thread's loop (main function), and here is the problem; since I use this C-function to start the thread in the run method, I pass the address of doOperation to the second parameter, and this cannot be done, because of type mismatch.

I've tried to use reinterpret_cast to return a pointer, but I ISO-C++ forbids returning a pointer of un-initialized function member. I don't know how to overcome this conflict, using a static method is the only solution I guess, but it blows up my designing pattern!

Josef
  • 353
  • 1
  • 2
  • 8
  • Michael, Stefan,Thanks you for your sharing your informative ideas, they've solved my problem. – Josef Feb 02 '09 at 00:29
  • See this answer to a similar question: - http://stackoverflow.com/questions/499153/passing-a-qualified-non-static-member-function-as-a-function-pointer/499299#499299 – Michael Burr Feb 01 '09 at 08:59

1 Answers1

7

First, be sure to read the link Michael Burr provided, as it contains good information. Then, here is C++ish pseudo-code for it:

int wrapperDoOperation(int v, void *ctx)
{
    Thread *thread = (Thread *)ctx;
    return thread->doOperation(v);
}

class Thread {
public:
    run() {
         startThread("bla", wrapperDoOperation, bla, bla, bla, (void *)this);
    }
    kill() { /*stop the thread*/ }
protected:
    virtual int doOperation(unsigned int) = 0;

friend wrapperDoOperation ......;
};

The idea is that doOperation, being a member function of Thread, doesn't need a void *context, you can just keep whatever you would pass as a context in the object itself. Therefore, you can use the void pointer to pass the actuall this pointer to the doOperation. Notice that the void * details are hidden from the users of your class, which is nice.

user51568
  • 2,623
  • 2
  • 20
  • 23
  • Also, you can check out a blogpost I recently made regarding this: http://nothingintoinsight.blogspot.com/2009/02/how-to-hack-closures-in-your-c-code-or.html – user51568 Feb 01 '09 at 20:13