Hello I'm working on a project where I need to use a function pointer in a static class member that points to a non-member function. When I try to do this it gives me a error: invalid use of member 'Thing::fp' in static member function. Help would be much appreciated!
fp is a simple member variable. Each object of type Thing will have a different fp associated with it. Start, however, is static and thus is not related to any specific object. Therefore it does not have a way to know what fp you want to use. The solution is either to remove static from Start or add static to fp. Note that the second option would require some more modifications.
Add FunctionPtr Thing::fp; after the class declaration (if you had the declaration in a header, you'd still need to put that line in a cpp file).
Remove the constructor (you can keep it, but remember that a constructor is for objects fp is for the whole class. If you do intend to create some instances, their constructors should not modify fp. It's ok to use it though). You may want to write staticvoid init(void (*p)()) instead (although plain = will work too).
Remember that when you use a static member, it will be Thing::Start() instead of mything.Start().
The issue is I need to acess it in a static member function but it needs to be unique for each class. I need to store function pointers for each instance of the class not for every instance :)
The issue is I need to acess it in a static member function but it needs to be unique for each class.
What you want and what you are doing are two opposite things.
static members exist once and all objects share the same instance of that member.
non-static members have a unique instance for all objects.
So based on what you are saying, you want unique instances. Therefore you do NOT want static. So get rid of ?all? static keywords here, as they are not what you want.
class MyClass
{
public:
staticvoid ThreadEntry(void* userdata)
{
MyClass* ptr = reinterpret_cast<MyClass*>(userdata);
ptr->RunThread();
}
void RunThread() // <- note: non-static
{
}
};
int main()
{
// start a new thread, give it a pointer to the static function
// and also give it a pointer to a MyClass object
MyClass obj;
start_another_thread( &MyClass::ThreadEntry, &obj );
}
Of course exactly how you specify the userdata will vary slightly depending on the API.
The thing is that the Thread must be static and it must call either a function by pointer stored in the class or be able to call a non-static function that would then execute the function by pointer.
that 'void *arg' argument is your user data. You want to pass a pointer to an object to that function. You can then use that object to call a non-static member.
1 2 3 4 5 6
staticvoid WorkerLauncherThread(void *arg)
{
Worker* ptr = reinterpret_cast<Worker*>(arg); // cast the argument to a pointer to this class
ptr->RunnerThreadFunction(); // <- call the non-member function using that object
_endthread();
}
The other part of this is passing a pointer to a valid object to _beginthread so that you get that pointer in your callback. This is what the 3rd parameter is for:
1 2
_beginthread( WorkerLauncherThread, 0, this ); // <- pass it 'this', which is a pointer
// to the current 'Worker' object. That pointer will then be 'arg' in your callback function.
Also, I DO NOT RECOMMEND using 'this' in your constructor. Starting a new thread in a class constructor is kind of a sketchy idea. Personally I would have a separate 'Start' function or something which actually fires up the new thread.