I did all the necessary configurations, like including Pthread library and header files...
The error is:
error C3867: 'FunctionClass::calledfunction': function call missing argument list; use '&FunctionClass::calledfunction' to create a pointer to member
Here's the example that causes the error:
class FunctionClass
{
public:
void * calledfunction( void *);
/*
this is the definition of the function in the FunctionClass.cpp
void * FunctionClass::calledfunction( void *)
{
//do sth;
}
*/
};
int main(void)
{
pthread_t process_m;
FunctionClass *obj = new FunctionClass ();
int nbr= 5;
if(pthread_create(&process_m,NULL,obj->calledfunction,(void *)nbr)< 0)
{
std::cout << "thread1";
}
}
What could cause the error? I respected the syntax of the function pthread_create... But I can't find the reason for this error!
You cannot use non-static member functions as callback.
Use a free function or a static member function as third parameter of pthread_create.
Edit to reflect OP's comment:
If you need to call a function member of FunctionClass for a specific FunctionClass object (obj in your example) the common way is that of calling a static member function (or a free one) passing your object to it, and then call object's member function from there.
Here an example (didn't test it, but it should let you understand what to do):
struct obj_arg_pair { FunctionClass *obj; int nbr; };
static void * calledfunctionStatic( void *args_ )
{
obj_arg_pair *args = reinterpret_cast< obj_arg_pair * >( args_ );
return args->obj->calledFunction( args->nbr );
}
and then start your thread with a code similar to this one:
obj_arg_pair args;
args.nbr = 5;
args.obj = obj;
pthread_create(&process_m,NULL,FunctionClass::calledfunction,(void *)&args);
calledfunction must be static or non class function.
Edit:
If you need to call nonstatic function do following.
struct forFunctionCalling
{
FunctionClass * ptr;
void * otherarguments;
};
void * somefunction (void * v)
{
forFunctionCalling * f_ptr = reinterpret_cast<forFunctionCalling>(v);
return f_ptr->ptr->calledfunction(f_ptr->otherarguments);
}
And call somefunction instead calledfunction.
P.S. Of course this code will look much better if you change type otherarguments from void * to it's real type
You need to do as the others here have suggested: create an "object" to hold all the data your function needs then pack that into the "void *" parameter. The function should be a free-function or a static class member function - the static member function if it needs access to private members of the class.
What I will add is how you must handle the lifetime of the objects you pack into your "void *" holder. You can:
use "new" to create it. You will know then it exists but must delete it at some point. You cannot pass shared_ptr to your thread-function but you can put shared_ptr in your thread-function itself if you know it was created for you with "new". You could also make the deleter one of the members of the packed struct, and use that in boost::shared_ptr so at call time you indicate how to clean up the data.
use wait mechanisms so the caller waits for the thread to "accept" the data before exiting where the objects will lose scope. The thread "accepts" after making copies of this data for its use. That way you can create a local struct of the data and pass that in.
You might consider using boost::thread although where you can pass in shared_ptr objects as parameters to boost::bind and write your function in a way to receive these.
Related
sorry for possible duplicates, but I didn't understand the examples and codes snippets I found.
I have a class named "EncoderWrapper" which includes some functions. One of these functions is called "onAfterTouch" and is declared in the "EncoderWrapper.h" file.
void onAfterTouch(byte channel, byte pressure);
The functions will become a callback for another class function of a library I use
inline void setHandleAfterTouch(void (*fptr)(uint8_t channel, uint8_t pressure)) {
usb_midi_handleAfterTouch = fptr;
};
Note: I'm totally new to C++, so I want to say sorry if I'm doing some "no-gos" or mixing up some terms.
The question is: How can I pass my class function (member function?) to that "setHandleAfterTouch" function of the library?
This won't work:
void EncoderWrapper::attachMIDIEvents()
{
usbMIDI.setHandleAfterTouch(&EncoderWrapper::onAfterTouch);
}
... my IDE says
no matching function for call usb_midi_class:setHandleAfterTouch(void (EncoderWrapper::*)(byte, byte))
I've also tried
usbMIDI.setHandleAfterTouch((&this->onAfterTouch));
But this won't work ... and I don't get the approach on that.
Every Help is very appreciated ;-)
Function pointer and member function pointer have different types. You can it for yourself:
struct Test {
void fun();
};
int main() {
void(*ptr)() = &Test::fun; // error!
}
Instead, member function pointer need this syntax:
void(Test::*fun)() = &Test::fun; // works!
Why you ask? Because member function need an instance to be called with. And calling that function have a special syntax too:
Test t;
(t.*funptr)();
To accept member function pointer, you'll need to change your code to this:
inline void setHandleAfterTouch(void(EncodeWrapper::*fptr)(uint8_t, uint8_t)) {
usb_midi_handleAfterTouch = fptr;
};
Since it's rather limiting accepting only the functions from one class, I recommend using std::function:
inline void setHandleAfterTouch(std::function<void(uint8_t, uint8_t)> fptr) {
usb_midi_handleAfterTouch = std::move(fptr);
};
This will allow you to send lambda with captures, and call your member function insode it:
// we capture this to use member function inside
// v---
usbMIDI.setHandleAfterTouch([this](uint8_t, channel, uint8_t pressure) {
onAfterTouch(channel, pressure);
});
It seems you can't change, and by looking quickly at the API, it doesn't seem you have access to a state object.
In that case, if you want to use your member function, you need to introduce a global state:
// global variable
EncodeWrapper* encode = nullptr;
// in your function that sets the handle
encode = this; // v--- No capture makes it convertible to a function pointer
usbMIDI.setHandleAfterTouch([](uint8_t, channel, uint8_t pressure) {
encode->onAfterTouch(channel, pressure);
});
Another solution would be to make onAfterTouch function static. If it's static, it's pointer is not a member function pointer, but a normal function pointer.
Ok so often times I have seen the following type of event handling used:
Connect(objectToUse, MyClass::MyMemberFunction);
for some sort of event handling where objectToUse is of the type MyClass. My question is how exactly this works. How would you convert this to something that would do objectToUse->MyMemberFunction()
Does the MyClass::MyMemberFunction give an offset from the beginning of the class that can then be used as a function pointer?
In addition to Mats' answer, I'll give you a short example of how you can use a non-static member function in this type of thing. If you're not familiar with pointers to member functions, you may want to check out the FAQ first.
Then, consider this (rather simplistic) example:
class MyClass
{
public:
int Mult(int x)
{
return (x * x);
}
int Add(int x)
{
return (x + x);
}
};
int Invoke(MyClass *obj, int (MyClass::*f)(int), int x)
{ // invokes a member function of MyClass that accepts an int and returns an int
// on the object 'obj' and returns.
return obj->*f(x);
}
int main(int, char **)
{
MyClass x;
int nine = Invoke(&x, MyClass::Mult, 3);
int six = Invoke(&x, MyClass::Add, 3);
std::cout << "nine = " << nine << std::endl;
std::cout << "six = " << six << std::endl;
return 0;
}
Typically, this uses a static member function (that takes a pointer as an argument), in which case the the objectToUse is passed in as a parameter, and the MyMemberFunction would use objectToUse to set up a pointer to a MyClass object and use that to refer to member variables and member functions.
In this case Connect will contain something like this:
void Connect(void *objectToUse, void (*f)(void *obj))
{
...
f(objectToUse);
...
}
[It is also quite possible that f and objectToUse are saved away somewhere to be used later, rather than actually inside Connnect, but the call would look the same in that case too - just from some other function called as a consequence of the event that this function is supposed to be called for].
It's also POSSIBLE to use a pointer to member function, but it's quite complex, and not at all easy to "get right" - both when it comes to syntax and "when and how you can use it correctly". See more here.
In this case, Connect would look somewhat like this:
void Connect(MyClass *objectToUse, void (Myclass::*f)())
{
...
objectToUse->*f();
...
}
It is highly likely that templates are used, as if the "MyClass" is known in the Connect class, it would be pretty pointless to have a function pointer. A virtual function would be a much better choice.
Given the right circumstances, you can also use virtual functions as member function pointers, but it requires the compiler/environment to "play along". Here's some more details on that subject [which I've got no personal experience at all of: Pointers to virtual member functions. How does it work?
Vlad also points out Functors, which is an object wrapping a function, allowing for an object with a specific behaviour to be passed in as a "function object". Typically this involves a predefined member function or an operatorXX which is called as part of the processing in the function that needs to call back into the code.
C++11 allows for "Lambda functions", which is functions declared on the fly in the code, that doesn't have a name. This is something I haven't used at all, so I can't really comment further on this - I've read about it, but not had a need to use it in my (hobby) programming - most of my working life is with C, rather than C++ although I have worked for 5 years with C++ too.
I might be wrong here, but as far as I understand,
In C++, functions with the same signature are equal.
C++ member functions with n parameters are actually normal functions with n+1 parameters. In other words, void MyClass::Method( int i ) is in effect void (some type)function( MyClass *ptr, int i).
So therefore, I think the way Connect would work behind the scenes is to cast the member method signature to a normal function signature. It would also need a pointer to the instance to actually make the connection work, which is why it would need objectToUse
In other words, it would essentially be using pointers to functions and casting them to a more generic type until it can be called with the parameters supplied and the additional parameter, which is the pointer to the instance of the object
If the method is static, then a pointer to an instance doesn't make sense and its a straight type conversion. I have not figured out the intricacies involved with non-static methods yet - a look at the internals of boost::bind is probably what you want to do to understand that :) Here is how it would work for a static function.
#include <iostream>
#include <string>
void sayhi( std::string const& str )
{
std::cout<<"function says hi "<<str<<"\n";
}
struct A
{
static void sayhi( std::string const& str )
{
std::cout<<"A says hi "<<str<<"\n";
}
};
int main()
{
typedef void (*funptr)(std::string const&);
funptr hello = sayhi;
hello("you"); //function says...
hello = (&A::sayhi); //This is how Connect would work with a static method
hello("you"); //A says...
return 0;
}
For event handling or callbacks, they usually take two parameters - a callback function and a userdata argument. The callback function's signature would have userdata as one of the parameters.
The code which invokes the event or callback would invoke the function directly with the userdata argument. Something like this for example:
eventCallbackFunction(userData);
In your event handling or callback function, you can choose to use the userdata to do anything you would like.
Since the function needs to be callable directly without an object, it can either be a global function or a static method of a class (which does not need an object pointer).
A static method has limitations that it can only access static member variables and call other static methods (since it does not have the this pointer). That is where userData can be used to get the object pointer.
With all this mind, take a look at the following example code snippet:
class MyClass
{
...
public:
static MyStaticMethod(void* userData)
{
// You can access only static members here
MyClass* myObj = (MyClass*)userdata;
myObj->MyMemberMethod();
}
void MyMemberMethod()
{
// Access any non-static members here as well
...
}
...
...
};
MyClass myObject;
Connect(myObject, MyClass::MyStaticMethod);
As you can see you can access even member variables and methods as part of the event handling if you could make a static method which would be invoked first which would chain the call to a member method using the object pointer (retrieved from userData).
I'm trying to create a thread in c++ with this code:
pthread_t mythread;
void* f (void*) = MyClass::myfunction;
pthread_create(&mythread, NULL, &f, NULL);
It's not working. Any idea what's wrong ?
myfunction is of type:
void* MyClass::myfunction(void* argv);
The error returned is:
error: declaration of ‘void* Class::f(void*)’ has ‘extern’ and is initialized
error: invalid pure specifier (only ‘= 0’ is allowed) before ‘::’ token
error: function ‘void* Class::f(void*)’ is initialized like a variable
You're declaring f as a function rather than a function pointer. It should be:
void* (*f) (void*) = &MyClass::myfunction;
^^^^
pthread_create(&mythread, NULL, f, NULL);
^ no & since it's already a pointer
This will also only work if myfunction is static, since you can't convert a pointer-to-member-function to a pointer-to-function.
If you do need to the thread to execute a non-static member function on a particular object, then one approach is to write a static wrapper taking the object as an argument:
class MyClass {
public:
void start_thread() {
// Pass "this" to the thread we're creating
pthread_create(&mythread, NULL, &MyClass::thread_entry, this);
}
private:
static void * thread_entry(void * object) {
// Call the member function on the object passed to the thread
return static_cast<MyClass*>(object)->thread();
}
void * thread() {
// do the interesting stuff, with access to the member variables
}
};
Of course, these days there's a standard thread library which removes the need for this dance:
std::thread thread(&MyClass::thread, this);
Pthreads expects a function pointer, and with classes, you can only point to a static method using a function pointer.
If you'd like to call a specific method of a class on a specific object, you need two separate parts of data:
pointer to a class method (don't confuse them with function pointers)
pointer to an object
These two joined together can be informally called a delegate.
PThreads is a C library, and to interoperate with it, you need a little workaround:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void*),
void *arg);
We're going to wrap the class method in a static class method, to be able to pass it as parameter start_routine, and we're going to pass the pointer to the object itself as arg.
See the code:
struct Foo {
// wrapper method
static void* threadStartingPoint(void* obj) {
return ((Foo)obj)->threadFunc();
}
// your target method itself
void* threadFunc() {
// this is where you do your logic
}
}
Such workaround allows you to use pthread_create(thread, attr, Foo::threadStartingPoint, someObject).
Note that if you are lucky enough to have a modern compiler which supports std::thread, you can use that instead of pthreads and have the code much simpler - you just need to create a std::function object and pass it to std::thread's constructor.
You simple can't do what you are trying to do - a member function (UNLESS it is static) needs an object in which to be called - that is the process starting the thread can't just call MyClass::f() because it needs to call something.f() - and it doesn;t know what something is.
Typically one gets around this by defining a static member function which takes the object as a parameter and then calls the member function on that object.
I have 2 classes
class B {
public:
int func(int i);
};
class A {
public:
typedef int (B::*fPtr)(int);
void run();
B* mB;
};
void A::run() {
// create a pointer
fPtr p = &(B::func);
// invoke the function
mB->*p(2); <------- Compilation Error
}
What i need is to create a pointer to func() in A's run function. I get a compilation error saying that mB is not corresponding to a function with 1 argument.
please help
You need to put parentheses around the function expression:
(mB->*p)(2);
But as others have pointed out, there's almost certainly a better way to do what you're trying to do.
Instance methods on a class always have a hidden first parameter for the this pointer, thus it is incompatible with your function pointer typedef. There is no way directly to obtain a pointer to a member function. The typical workaround is to use a "thunk" where you pass a static function that accepts a generic "catch all" parameter (such as void *) which can be statically cast to a pointer of your choosing on which you can invoke the member function. Example:
class B
{
public:
static void MyThunk(void * obj)
{
static_cast<B *>(obj)->MyRealFunc();
}
void MyRealFunc()
{
// do something here
}
// . . .
};
You can get a pointer to the static function easily as it has no 'hidden this', just reference it using B::MyThunk. If your function requires additional parameters, you can use something like a functor to capture the necesssary parameters and state.
You should definitely read this C++ FAQ Lite page which tells you much more about all this: Pointers to member functions
why can you not call mB->func(2);?
If you need different functions for B perhaps look into virtual functions and class inheritance
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.