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!
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.
Related
I have the following class:
class Foo {
private:
Bar *_bar;
void *run(void *);
public:
Foo(Bar *bar);
}
I want Foo::Foo to launch a thread running Foo::run.
I know this can be done using std::thread:
Foo::Foo(Bar *bar) : _bar(bar) {
_thread = std::thread(&Foo::run, this);
}
The problem is I need to set a priority and a scheduling policy for this thread - which can be achieved using pthread.
(very) sadly, I cannot change the design of the system and I have to spawn the thread inside of the C'tor.
pthread is a C API and I can't figure out how to run it on a nonstatic member function. The following attempts did not compile:
Foo::Foo*(Bar *bar) : _bar(bar) {
// attempt 1
pthread_create(&thread, NULL, &Foo::run, this);
// attempt 2
pthread_create(&thread, NULL, (void* (*)(void *))(&Foo::run), this);
}
From the pthread_create man page - the third argument (start_routine) is a pointer to a function returning void * and receiving void *.
The calling conventions for C and C++ are totally different because a C++ function (unless static) needs to know which instance of a class to call its member function with.
What you can do is have a static function and the incoming parameter is the instance pointer. Like this:
class Foo
{
private:
Bar *_bar;
static void *start_thread(void *ptr) { return dynamic_cast<MyThread *>(ptr)->run(); }
void *run(); // Implement thread here.
public:
Foo(Bar *bar);
}
Foo::Foo(Bar *bar) : _bar(bar) {
pthread_create(&thread, NULL, Foo::start_thread, this);
}
Member functions aren't like free functions. They need an instance of the class to be invocable. As such, the type system treats them differently and pointers to member functions are not like regular pointers to free functions. std::thread uses templates to present a convenience API that can accept either.
Naturally, pthreads aren't templated, and don't account for anything that isn't a free function. To make it run a member function on an object, you need a trampoline function. A function that can decay to a free function pointer, and contains code to execute your member on the instance you pass as void.
If you find yourself needing those often, you can write a template that will generate them for you. Like so:
template<class C, void* (C::* run_mem)()> // Member function without argumnets
void* pthread_member_wrapper(void* data) {
C* obj = static_cast<C*>(data)
return (obj->*run_mem)();
}
So if you define run as void *run();, you can use the above wrapper anywhere run is accessible:
Foo::Foo*(Bar *bar) : _bar(bar) {
pthread_create(&thread, NULL,
pthread_member_wrapper<Foo, &Foo::run>,
this);
}
Since pthread_member_wrapper is templatized on a class and member function pointer, you can reuse it with any class, in any scope where that member is accessible. It doesn't have to be a member of Foo itself.
I have a question related with C++ and threads.
I am more familiar with Java than C++ and this error is confusing me.
Imagine that in x.h file I have a class such as:
class A{
public A();
public virtual void* func(void*);
public virtual void func2();
public virtual void func3();
};
In x.cpp file I want to do that:
void* A::func(void*) {
while(....)
func2();
return NULL;
}
void A::func2() {
...some stuff there...
}
void A::func3() {
pthread_t t1;
pthread_create(&t1, NULL, &A::func, NULL);
void* result;
pthread_join(t1,&result);
...some other stuff...
}
The problem is it hangs with the following error:
"error: ISO C++ forbids taking the address of an unqualified or
parenthesized non-static member function to form a pointer to member
function."
What should I do to fix this?
Thanks.
This is a lousy error message, but fundamentally what it's trying to tell you is that you can't form a function pointer from an instance method (I'm not sure what Java's terminology here is). This is because to call an instance method you need both the address of the actual code and the address of an object to be this, and a regular function pointer only stores the former.
What you need here is a static wrapper method which matches pthread_create's expectations of the thread start routine. You pass this as the fourth argument to pthread_create, and the wrapper converts its argument back to an object pointer and invokes func. This type of wrapper is commonly known as a "thunk", since it adapts one calling convention to another.
class A {
// ...
static void* thread_start_thunk(void* self);
};
void*
A::thread_start_thunk(void* self)
{
return static_cast<A*>(self)->func();
}
// ...
void
A::func3()
{
// ....
pthread_create(&t1, 0, &A::thread_start_thunk, static_cast<void*>(this));
// ...
}
The casts are unavoidable.
You can not just pass a pointer to a method to the thread. That method-pointer alone would not mean anything, because it does not know which instance it belongs to. If you need to call an instance method in a different thread, add a private static method to the class and pass it's address to the thread, along with a pointer to the instance as an argument.
That static method could look somewhat like this:
class A
{
public: virtual void threadMethod();
public:
static void staticThreadMethod(void* instanceObj)
{
((A*)instanceObj)->threadMethod();
}
};
I did not test that code and it obviously does not check for errors, but this is how I usually do it.
use one of:
boost::thread
C++11
some other C++ library threads (a plenty of them)
add a static method to your class, then pass its address to pthread_create w/ user provided void* to pair of your class instance (pointer/ref) and class::*method you want to call. then in static function just call desired method using instance and method address obtained from parameter
In pthread_create(&t1, NULL, &func, NULL); you try to take the address of a member function. There are two issues with that
The correct form is
&A::func
this is what the compiler tries to tell you.
pthread_create wants a pointer to function, not a pointer to a non-static member function. What you can do instead is, creating a static member function and passing the address of this static member function as an argument to pthread_create.
Example:
class A {
public:
static void *func(void *);
};
pthread_t t1;
pthread_create(&t1, NULL, &A::func, NULL);
can I use thread in member function to call a member function for C++ in windows? If yes, how to implement it? Here is the sample
void Class::fun_1(void){
_beginthread(fun_2, 0, NULL); //This is the error line :: function call missing argument list; use '&Class::fun_2' to create a pointer to member
}
void Class::fun_2(void){
printf("hello");
}
Thanks
There are actually multiple issues here:
You can't pass a pointer to a member function as the routine to the _beginthread() function. The function requires a pointer to a global or static function.
Standard C++ requires that you fully qualify the member function name (even within the class) and use an & to obtain a pointer to the member (the compiler was complaining to you about this point).
Because you can't pass a member function pointer to _beginthread(), you need to create a wrapper global or static function to make it work. Here's one way to make that happen:
class MyClass
{
public:
void fun_1()
{
_beginthread(&MyClass::fun_2_wrapper, 0, static_cast<void*>(this));
}
private:
void fun_2()
{
printf("hello");
}
static void __cdecl fun_2_wrapper(void* o)
{
static_cast<MyClass*>(o)->fun_2();
}
};
Of course, you need to somehow guarantee that the MyClass object will still exist for as long as fun_2() is running, or not-so-good things will happen. If you much rather not have to worry about it, consider using Boost.Thread which does basically this and much more for you.
The usual way to do this is to use a static member function that calls the member function using a void pointer to the original object.
class Class
{
public:
void fun_1(void)
{
_beginthread( &Class::static_fun_2, 0, this );
}
void fun_2(void)
{
printf("hello");
}
private:
static void static_fun_2( void * args )
{
static_cast<Class*>(args)->fun_2();
}
};
However if you start needing to pass arguments to those functions things get a little more complicated. I'd look at using boost::thread and boost::bind instead of rolling your own.
As the title says.
The following is my code skeleton.
class CLASS
{
public:
void A();
private:
DWORD WINAPI B(LPVOID);
};
void CLASS::A()
{
DWORD (WINAPI CLASS::*thread)(LPVOID) = &CLASS::B;
...
CreateThread(NULL, 0, thread, &arg, 0, NULL);
...
}
the function B needs CLASS's member variables.
But I've got an error code when I compiled this.
It's " can't convert argument 3 from 'DWORD (__stdcall CLASS::* )(LPVOID)' to 'LPTHREAD_START_ROUTINE' " or something like that.
I don't know if it is the same in the english environment.
can anybody help please?
Seriously, use std::thread:
class CLASS
{
public:
void A();
private:
void B(your args go here);
};
void CLASS::A()
{
std::thread t(&CLASS::B, this, your args go here);
// when done
t.join();
// or
t.detach();
}
Explanation
Your code doesn't compile because CreateThread is a C API, expecting a non-member C function as a callback. In order to call a non-static member function of a C++ class, the caller needs to know about this pointer and how to correctly use it. Since WinAPI clearly doesn't have this and doesn't expect a member function pointer, this cannot possibly work. Your compiler catches this and reports it as a type mismatch error.
This is where the lpParameter of CreateThread comes into play. It allows you to pass this through that parameter. However it doesn't change the fact that CreateThread doesn't know how to call C++ member functions. Therefore it's your responsibility to wrap it in a static function that will do the member function call:
class CLASS
{
public:
void A();
private:
DWORD B();
static DWORD s_B(LPVOID);
};
DWORD CLASS::s_B(LPVOID that) {
return ((CLASS*)that)->B();
}
void CLASS::A() {
CreateThread(NULL, 0, s_B, this, 0, NULL);
}
This is what #Nawaz does in their answer, except in a slightly more general way.
Even though this approach works, it clearly has downsides:
It's verbose.
It's non portable.
You need to pass your original args through different means (e.g. through a member of your class).
std::thread already does all that for you.
You've to define your callback function as static function if it's member function!
Better design : define a reusable class!
From my previous answer: (with little modification)
Even better would be to define a reusable class with pure virtual function run() to be implemented by the derived thread classes. Here is how it should be designed:
//runnable is reusable class. All thread classes must derive from it!
class runnable
{
public:
virtual ~runnable() {}
static DWORD WINAPI run_thread(LPVOID args)
{
runnable *prunnable = static_cast<runnable*>(args);
return prunnable->run();
}
protected:
virtual DWORD run() = 0; //derived class must implement this!
};
class Thread : public runnable //derived from runnable!
{
public:
void newthread()
{
CreateThread(NULL, 0, &runnable::run_thread, this, 0, NULL);
}
protected:
DWORD run() //implementing the virtual function!
{
/*.....your thread execution code.....*/
}
}
You have to make that member function static.
The problem here is that every non-static member function has an implicit this parameter and that's in fact what the compiler is trying to tell you - your nin-static member function has signature different from the one you expected.
Also see this answer to a closely related question.
I have a function pointer defined by:
typedef void (*EventFunction)(int nEvent);
Is there a way to handle that function with a specific instance of a C++ object?
class A
{
private:
EventFunction handler;
public:
void SetEvent(EventFunction func) { handler = func; }
void EventOne() { handler(1); }
};
class B
{
private:
A a;
public:
B() { a.SetEvent(EventFromA); } // What do I do here?
void EventFromA(int nEvent) { // do stuff }
};
Edit: Orion pointed out the options that Boost offers such as:
boost::function<int (int)> f;
X x;
f = std::bind1st(
std::mem_fun(&X::foo), &x);
f(5); // Call x.foo(5)
Unfortunately Boost is not an option for me. Is there some sort of "currying" function that can be written in C++ that will do this kind of wrapping of a pointer to a member function in to a normal function pointer?
You can use function pointers to index into the vtable of a given object instance. This is called a member function pointer. Your syntax would need to change to use the ".*" and the "&::" operators:
class A;
class B;
typedef void (B::*EventFunction)(int nEvent)
and then:
class A
{
private:
EventFunction handler;
public:
void SetEvent(EventFunction func) { handler = func; }
void EventOne(B* delegate) { ((*delegate).*handler)(1); } // note: ".*"
};
class B
{
private:
A a;
public:
B() { a.SetEvent(&B::EventFromA); } // note: "&::"
void EventFromA(int nEvent) { /* do stuff */ }
};
Run away from raw C++ function pointers, and use std::function instead.
You can use boost::function if you are using an old compiler such as visual studio 2008 which has no support for C++11.
boost:function and std::function are the same thing - they pulled quite a bit of boost stuff into the std library for C++11.
Note: you may want to read the boost function documentation instead of the microsoft one as it's easier to understand
I highly recommend Don Clugston's excellent FastDelegate library. It provides all the things you'd expect of a real delegate and compiles down to a few ASM instructions in most cases. The accompanying article is a good read on member function pointers as well.
http://www.codeproject.com/KB/cpp/FastDelegate.aspx
You may find C++ FAQ by Marshall Cline helpful to what you're trying to accomplish.
Read about pointers to members.
To call a method on the derived class, the method has to be declared in the base class as virtual and overriden in the base class and your pointer should point to the base class method. More about pointers to virtual members.
If you're interfacing with a C library, then you can't use a class member function without using something like boost::bind. Most C libraries that take a callback function usually also allow you to pass an extra argument of your choosing (usually of type void*), which you can use to bootstrap your class, as so:
class C
{
public:
int Method1(void) { return 3; }
int Method2(void) { return x; }
int x;
};
// This structure will hold a thunk to
struct CCallback
{
C *obj; // Instance to callback on
int (C::*callback)(void); // Class callback method, taking no arguments and returning int
};
int CBootstrapper(CCallback *pThunk)
{
// Call the thunk
return ((pThunk->obj) ->* (pThunk->callback))( /* args go here */ );
}
void DoIt(C *obj, int (C::*callback)(void))
{
// foobar() is some C library function that takes a function which takes no arguments and returns int, and it also takes a void*, and we can't change it
struct CCallback thunk = {obj, callback};
foobar(&CBootstrapper, &thunk);
}
int main(void)
{
C c;
DoIt(&c, &C::Method1); // Essentially calls foobar() with a callback of C::Method1 on c
DoIt(&c, &C::Method2); // Ditto for C::Method2
}
Unfortunately, the EventFunction type cannot point to a function of B, because it is not the correct type. You could make it the correct type, but that probably isn't really the solution you want:
typedef void (*B::EventFunction)(int nEvent);
... and then everything works once you call the callback with an obhect of B. But you probably want to be able to call functions outside of B, in other classes that do other things. That is sort of the point of a callback. But now this type points to something definitely in B. More attractive solutions are:
Make B a base class, then override a virtual function for each other class that might be called. A then stores a pointer to B instead of a function pointer. Much cleaner.
If you don't want to bind the function to a specific class type, even a base class (and I wouldn't blame you), then I suggest you make the function that gets called a static function: "static void EventFrom A(int nEvent);". Then you can call it directly, without an object of B. But you probably want it to call a specific instance of B (unless B is a singleton).
So if you want to be able to call a specific instance of B, but be able to call non-B's, too, then you need to pass something else to your callback function so that the callback function can call the right object. Make your function a static, as above, and add a void* parameter which you will make a pointer to B.
In practice you see two solutions to this problem: ad hoc systems where you pass a void* and the event, and hierarchies with virtual functions in a base class, like windowing systems
You mention that boost isn't an option for you, but do you have TR1 available to you?
TR1 offers function, bind, and mem_fn objects based on the boost library, and you may already have it bundled with your compiler. It isn't standard yet, but at least two compilers that I've used recently have had it.
http://en.wikipedia.org/wiki/Technical_Report_1
http://msdn.microsoft.com/en-us/library/bb982702.aspx
It's somewhat unclear what you're trying to accomplish here. what is clear is that function pointers is not the way.
maybe what you're looking for is pointer to method.
I have a set of classes for this exact thing that I use in my c++ framework.
http://code.google.com/p/kgui/source/browse/trunk/kgui.h
How I handle it is each class function that can be used as a callback needs a static function that binds the object type to it. I have a set of macros that do it automatically. It makes a static function with the same name except with a "CB_" prefix and an extra first parameter which is the class object pointer.
Checkout the Class types kGUICallBack and various template versions thereof for handling different parameters combinations.
#define CALLBACKGLUE(classname , func) static void CB_ ## func(void *obj) {static_cast< classname *>(obj)->func();}
#define CALLBACKGLUEPTR(classname , func, type) static void CB_ ## func(void *obj,type *name) {static_cast< classname *>(obj)->func(name);}
#define CALLBACKGLUEPTRPTR(classname , func, type,type2) static void CB_ ## func(void *obj,type *name,type2 *name2) {static_cast< classname *>(obj)->func(name,name2);}
#define CALLBACKGLUEPTRPTRPTR(classname , func, type,type2,type3) static void CB_ ## func(void *obj,type *name,type2 *name2,type3 *name3) {static_cast< classname *>(obj)->func(name,name2,name3);}
#define CALLBACKGLUEVAL(classname , func, type) static void CB_ ## func(void *obj,type val) {static_cast< classname *>(obj)->func(val);}