Here is my Code:
I want to use a class inside my custom MyStateMachine. I do not want to inherit de StateMachine class as I just want to use it with its functions. The MyStateMachine class is only to encapsulate a few things.
MyStateMachine.h
#include <StateMachine.h>
class MyStateMachine {
public:
void Initialisation();
private:
StateMachine machine = StateMachine();
State* m0Initialisation = machine.addState(&Initialisation); // problem here
};
MyStateMachine.cpp
#include "MyStateMachine.h"
void MyStateMachine::Initialisation() {
// do initialisation stuff here
}
machine.addState expects a function pointer as argument:
State* addState(void (*functionPointer)());
I get the following error message:
error: no matching function for call to 'StateMachine::addState(void (MyStateMachine::*)())
note: State* StateMachine::addState(void (*)())
State* addState(void (*functionPointer)());
note: no known conversion for argument 1 from 'void (MyStateMachine::*)()' to 'void (*)()'
Compilation error: no matching function for call to 'StateMachine::addState(void (MyStateMachine::*)())'
If I define the function outside the class, I can successfully pass this function as a function pointer (&Initialization).
I guess it has something to do that it is a function of a class and it needs the reference to the object. But even with that I did not find a solution.
How could I pass the function? If possible without external libraries (e.g. std::bind).
I have looked at a few posts but could not find a proper solution.
pass-an-objects-member-function-as-argument-function-pointer
class-member-function-as-function-pointer
using-pointers-to-member-to-pass-member-function-as-arguments
There is some different solutions to your problem.
1: Change the type of your funciton pointer in Statemachine::addState(...) to be a function pointer to a member type instead of a function pointer to a non member function.
Check out section "Pointers to members" here
2: Use std::function as the type of addState and do
State* m0Initialisation = machine.addState([this]() {Initialisation(); });
3: Change Initialization to be static and send in a pointer to your class every time you call the function.
static void Initialisation(StateMachine &self);
The problem is that StateMachine::addState expects a normal function pointer, which is different from a member function pointer. You can make your Initialization function static. Then the member function pointer is essentially a normal function pointer:
struct State {};
struct StateMachine {
State* addState (void (*)()){ return nullptr; }
};
class MyStateMachine {
public:
static void Initialisation();
private:
StateMachine machine = StateMachine();
State* m0Initialisation = machine.addState(&Initialisation); // no problem here
};
Member functions always have an implicit first argument, which is a pointer or reference to an instance of the class. This is the main difference between a normal function pointer and a member function pointer. So taking the implicit argument into account, the member function is not a void nullary function with signature `void (*)(). Static member functions do not have an implicit first argument, so member function pointers to static member functions can be treated like normal function pointers.
Related
I want a function that can be called inside of another class which has a single input parameter of type void function pointer. Inside the function, the function pointer should execute the function to which it's pointing.
// inside TestClass.h
class TestClass
{
public:
template<class UserClass>
static void TestingFctPtrStatic(void (UserClass::* TestFunction)(void), UserClass* Object);
};
template<class UserClass>
inline void TestClass::TestingFctPtrStatic(void (UserClass::* TestFunction)(void), UserClass* Object)
{
Object->TestFunction();
}
Calling the function inside the constructor of TestClass like this gives me the following compile error:
// inside TestClass.cpp
TestClass::TestClass()
{
TestClass::TestingFctPtrStatic<TestClass>(&TestClass::PrintStuff, this);
}
With PrintStuff():
void TestClass::PrintStuff()
{
std::cout << "Printing stuff!" << std::endl;
}
error C2039: 'TestFunction': is not a member of 'TestClass'
message : see declaration of 'TestClass'
message : see reference to function template instantiation 'void TestClass::TestingFctPtrStatic(void (__cdecl TestClass::* )(void),UserClass *)' being compiled
with
[
UserClass=TestClass
]
Edit:
I fixed it by using more parentheses in the implementation:
template<class UserClass>
inline void TestClass::TestingFctPtrStatic(void (UserClass::* TestFunction)(void), UserClass* Object)
{
(Object->*TestFunction)();
}
void(UserClass::* TestFunction)(void)
This is not a pointer to a function. It is a pointer to a class method.
TestFunction();
You can't just call a class method out of thin air. You need an object, an instance of the class, whose method gets called. If p is a pointer to a UserClass, in other words:
UserClass *p=(points to somewhere);
then you would invoke its method using this syntax:
(p->*TestFunction)();
It is unclear from your question's description where the object whose method gets invoked comes from, so you need to figure it out, yourself, based on all the other information you have but was not included in the question. In some form or fashion you'll need to find a UserClass object, somewhere -- either passed in as an additional parameter, or it's lying around, somewhere, in the general vicinity -- and then you can use the TestFunction pointer to invoke this object's method.
This is fundamental to C++, provided that this is a class method. If this PrintStuff is a static class method, then this would be, indeed, a plain old function pointer:
void (*TestFunction)();
And it would get invoke, via a pointer, no differently than any other function.
I have two claces.
here is the first one
class one{
one(){ }
public:
void change(double a){
//print a
}
void run(){
two tw;
tw->functionpointer=&change;
}
};
and here is the two class
public two{
two();
static void progresschange(double v){
functionpointer(v);
}
public:
void (*functionpointer)(double);
};
as you see in example I have a function in class one, I want to call it from an static function in class two As progresschange is static I can only call change function in class one uisng function pointers. but It does not work and compiles says
error: cannot convert ‘void (one::*)(double)’ to ‘void (*)(double)’ in assignment
it happens in this line
tw->functionpointer=&change;
how can I make it work. it is even possible to pass a function using its function pointer to another class using this method?
thanks
The error message is quite straightforward:
error: cannot convert void (one::*)(double) to void (*)(double) in assignment
void one::change(double) is a member function of the class one, not just a function. Therefore, you can't assign a pointer to this member function (i.e.: void (one::*)(double)) to a pointer to a function with the same signature (i.e.: to a void (*)(double)).
Besides, a non-static member function (like one::change() above) has to be called on an object, so you also need to provide an one object to call that pointed-to non-static member function.
Basically, you can achieve what you want by adding the following data members in two:
void (one::*mem_func_ptr)(double);
one *obj_ptr;
That is, a pointer to the member function (mem_func_ptr) and a pointer to the object to call this member function on (obj_ptr).
To assign to the member function pointer:
mem_func_ptr = &one::change;
Then, to call the member function pointed by mem_func_ptr on the object pointed by obj_ptr with 0.0 as argument:
(obj_ptr->*mem_func_ptr)(0.0);
It can be done analogously by keeping a copy of an object one as data member instead of a ponter. In that case you should use the operator .* instead of ->*.
The problem is that one::change() is a class member so you need to pass a pointer to a class instance as well.
The modern way to do it is to use std::function, std::bind and std::mem_fn:
class two {
....
std::function<void(double)> functionpointer;
}
tw->functionpointer = std::bind(std::mem_fn(&one::change), _1, one_instance);
Alternatively you can use a lambda function:
tw->functionpointer = [&one_instance](double x) { one_instance->change(x); }
I want to know the way to pass a member function to pthread_clean_push. I don't want to declare the cleanup function as static and pass object's reference to it. Below is the scenario
class Foo{
public:
Foo(string name):name(name){};
void setBar1(){bar1=malloc(4);sleep(20);};
void setBar2(){bar2=malloc(10);sleep(50);};
void cleanBar1(void* arg){free(bar1);};
void cleanBar2(void* arg){free(bar2);};
private:
string name;
void* bar1;
void* bar2;
};
void* myPThread(void* arg){
Foo theFoo(*(string*)(arg));
theFoo.setBar1();
pthread_cleanup_push(&theFoo.cleanBar1,NULL); //what is the correct way to
theFoo.setBar2();
pthread_cleanup_push(&theFoo.cleanBar2,NULL); //pass clean functions?
sleep(100);
pthread_cleanup_pop(1);
pthread_cleanup_pop(1);
return NULL;
}
int main(){
string biryani="biryani";
string pappu="pappu";
pthread_t makeBirayani, makePappu;
pthread_create(&makeBiryani,NULL,&myPThread,(void*)&biryani);
pthread_create(&makePappu,NULL,&myPThread,(void*)&pappu);
pthread_join(makeBiryani,NULL);
pthread_join(makePappu,NULL);
return 0;
}
I avoided compile-time error ISO C++ forbids taking the address of a bound member function to form a pointer to member function by using (void(*)(void*))&Foo::cleanBar1 as the argument to pthread_cleanup_push(). But run-time error(segmentation fault) occurs with multiple threads as it has ambiguity in determining the instance to which the cleanup function belongs. How to invoke the member function like here in this scenario? What is the syntax?
Foo::cleanBar1 and Foo::cleanBar2 are non-static member functions, which means that they take an implicit first argument, a pointer to the Foo instance on which they must be invoked (the this pointer). So you cannot pass a pointer to member function to pthread_cleanup_push and get the desired behavior.
You'll need to create a dispatcher function that calls the member function you want, and then pass a pointer to that function to pthread_cleanup_push. This dispatch function could either be a free function, or a static member function of Foo. For instance,
class Foo{
public:
Foo(string name):name(name){}
void setBar1(){bar1=malloc(4);sleep(20);}
void cleanBar1(){free(bar1);}
static void bar1_callback(void *arg)
{
static_cast<Foo*>(arg)->cleanBar1();
}
// ..
private:
string name;
void* bar1;
void* bar2;
};
And then pass it to pthread_cleanup_push as
pthread_cleanup_push(&Foo::bar1_callback, &theFoo);
Now the call to pthread_cleanup_pop will execute Foo::bar1_callback and pass it a pointer to the theFoo instance, which will then invoke the cleanBar1() member function.
The member function needs to know the object for which it is executed. This is why the standard doesn't allow this direct reference.
Just use a lambda-wrapper, like:
pthread_cleanup_push( [](void*a)->void { reinterpret_cast<Foo*>(a)->cleanBar1(NULL);},
&theFoo); //&theFoo will be passed as argument to the function
However you MUST ensure that your theFoo object still exist when the cleanup is called, because you give its adress when you push the cleanup function, and this address will later be used as argument for the cleanup by the lambda function.
From my understanding of the pthread function pthread_cleanup_push function you can pass the address of a free function (or possibly static to the class Foo) to it and a pointer to an object and then route the call to the correct member.
void clean_bar_1(void* arg)
{
Foo* p = static_cast<Foo*>(arg);
p->cleanBar1();
}
And then in myPThread function:
pthread_cleanup_push(&clean_bar_1, &theFoo);
And repeat for the cleanBar2 method.
I have a bit complicated class.
In this class I have a reference:
Private:
IEtApiPtr _pIEtApi;
IEtApiPtr is defined in a .tlh file:
_COM_SMARTPTR_TYPEDEF(IEtApi, __uuidof(IEtApi));
IEtApiPtr has a void named "SetRawDataCB"
virtual HRESULT __stdcall SetRawDataCB (
/*[in]*/ long address,
/*[in]*/ long userData,
/*[out,retval]*/ enum ApiError * pRetVal ) = 0;
I have defined a callback function in the class:
void CETAPI::RawDataCB(RawData& r, void* userData)
{
//do something
}
Now I want to install a callback using
_pIEtApi->SetRawDataCB((long)(__int64)(&RawDataCB),0,&result);
... the compiler tells me "Error C2276: Invalid operation for expression of a bound member function".
What did I do wrong here?
This doesn't work because RawDataCB is a member function not a global function. You can declare RawDataCB as a static function in the class as follows and this will work. However you will no longer have access to the this pointer (i.e. no member variables) unless you add it as a parameter to RawDataCB and perhaps make RawDataCB a friend to gain access to private data of the class as a member function would have. This can be done by updating the function declaration as follows:
class CETAPI {
static void RawDataCB(RawData& r, void* userData);
};
Alternatively, you can pass a pointer to RawDataCB as a member function pointer rather than a function pointer. Member function pointers can be manipulated as follows, so you will just pass an object of type RawDataCBType to SetRawDataCB.
typedef void (CETAPI::*RawDataCBType)(RawData&, void*); // typedef the member function pointer type
RawDataCBType pmf = &CETAPI::RawDataCB; // create and initialize a pointer to the member function
pCETAPIObject->*pmf(r, userData); // call the member function on an object of type CETAPI
Here is a good article that talks about member pointers.
In This case compiler founds problem in the syntax
use following line of code
pIEtApi->SetRawDataCB((long)(_int64)(&CETAPI::RawDataCB),0,&result);
see the link for more info Error code description
Currently in the program I am attempting to write I need to be able to get a pointer to a member function within a member function of the same class. The pointer needs to be passed to a function as a void (*)(). Example:
//CallFunc takes a void (*)() argument
class testClass {
public:
void aFunc2;
void aFunc1;
}
void testClass:aFunc2(){
callFunc(this.*aFunc1); // How should this be done?
}
void testClass:aFunc1(){
int someVariable = 1;
}
I'm trying to do this in GCC 4.0.1. Also, the member function being called can't be static because it references non-static variables in the class that it is part of. (In case you are wondering, the specific instance in which I need this is where I need to be able to pass a member function of a class to the GLUT function glutDisplayFunc() )
To take pointer to member function you need following syntax:
callFunc(&testClass::aFunc1);
But note, that to invoke member function you need have class instance. So callFunc needs 2 parameters (I'm using template but you can change it to testClass):
template <class T>
void callFunc(T*inst, void (T::*member)())
{
(inst->*member)();
}
So correct call of callFunc looks like:
void testClass::aFunc2()
{
callFunc(this, &testClass::aFunc1);
}