I need to assign a callback function with given parameters, so when the event gets triggered and the callback function is called, it calls the function with given parameters. I've looked at multiple websites and I've been trying to find a solution but no luck. Might be that I'm just so dumb, what can I do?
Here's a bit of what I'm trying to do -
void callbackFunction(int someParameter) {
// Do something here
}
master.ButtonL1.pressed(callbackFunction(3));
// The code above doesn't work, just there to show what I'm wanting to do
You can use lambda.
master.ButtonL1.pressed([]{callbackFunction(3);});
In addtion to using a lambda expression, as suggested in the answer by songyuanyao, you can use the following method.
void realCallbackFunction(int someParameter)
{
// DO the real work
}
static int parameter = 0;
void callbackFunction()
{
realCallbackFunction(paramter);
}
...
paramter = 3;
master.ButtonL1.pressed(callbackFunction);
Related
I haven't used C++ in ages. Between what I've forgotten and what has changed in C++ over time, I'm really banging my head against the wall trying to do something that would be trivially easy in JavaScript, or any other language where functions are objects, and not just simple pointers.
I think I understand the basic problem: A class member function only exists in once place in memory (there isn't a different copy of it for each class instance). The only way the function knows what "this" is is because an instance pointer is passed along as an invisible first argument to every function call. A plain-old C-style callback isn't going to know anything about passing that instance pointer.
What I need is a new function that is somehow bound to my class instance, one which knows how to pass "this" along to the member function. That's the function I need to use as a callback.
But I don't know for sure how to dynamically create such a function. I think the code below is on the right track (except for casting pointer types), but it does bother me a bit because it seems like that there'd have to be some dynamic memory allocation going on, and if so, some way to track that allocation and do clean-up later.
class SignalMonitor {
int dataPin;
unsigned short timings[RING_BUFFER_SIZE];
unsigned long lastSignalChange = 0;
int dataIndex = 0;
int syncCount = 0;
void signalHasChanged();
public:
SignalMonitor(int);
};
SignalMonitor::SignalMonitor(int dataPin) {
this->dataPin = dataPin;
function<void()> callback = bind(&SignalMonitor::signalHasChanged, this);
wiringPiISR(dataPin, INT_EDGE_BOTH, callback);
}
void SignalMonitor::signalHasChanged() {
unsigned long now = micros();
int duration = (int) min(now - this->lastSignalChange, 10000ul);
this->lastSignalChange = now;
cout << duration << '\n';
}
I feel like this is close to what I want, but I'm getting this error:
acu-rite-433Mhz-reader.cpp:58:72: error: invalid cast from type ‘std::function<void()>’ to type ‘void*’
wiringPiISR(dataPin, INT_EDGE_BOTH, reinterpret_cast<void *>(callback));
^
Here's the call signature of the function I'm trying to pass this callback to:
int wiringPiISR (int pin, int edgeType, void (*function)(void))
I've found a number of similar issues discussed when searching on this topic, but they either don't quite match what I'm trying to do, or assume much more familiarity with C++ than I currently possess. (All I remember about function pointer types is that they can get hellishly ugly very quickly!)
I tried to use lambda function as a solution, but that led to an error (besides a type mismatch error) about something being "temporary", which I'm assuming meant that the lambda function's scope was temporary.
This is a far from ideal solution (I'm beginning to think there are no ideal solutions here), but it works for me in this particular case where there aren't likely to be very many instances of my SignalMonitor class in use at the same time.
First, I turned my signalHasChanged class method into a static method that takes an instance as an argument. (I could have kept the method as a class method by going through some hairy type-casting, but it wasn't worth it.)
Then I made ten almost-identical indirect callback functions:
void smCallback0() { SignalMonitor::signalHasChanged(monitors[0]); }
void smCallback1() { SignalMonitor::signalHasChanged(monitors[1]); }
void smCallback2() { SignalMonitor::signalHasChanged(monitors[2]); }
void smCallback3() { SignalMonitor::signalHasChanged(monitors[3]); }
void smCallback4() { SignalMonitor::signalHasChanged(monitors[4]); }
void smCallback5() { SignalMonitor::signalHasChanged(monitors[5]); }
void smCallback6() { SignalMonitor::signalHasChanged(monitors[6]); }
void smCallback7() { SignalMonitor::signalHasChanged(monitors[7]); }
void smCallback8() { SignalMonitor::signalHasChanged(monitors[8]); }
void smCallback9() { SignalMonitor::signalHasChanged(monitors[9]); }
Then I stuck all of those functions into an array:
void (*_smCallbacks[MAX_MONITORS])() = {
smCallback0, smCallback1, smCallback2, smCallback3, smCallback4,
smCallback5, smCallback6, smCallback7, smCallback8, smCallback9
};
Along with the monitors array, which is an array of SignalHandler pointers, this gives me ten available callback slots. (_smCallbacks is copied into smCallbacks as a way to get around foreward reference problems.)
The init method for SignalMonitor simply searches for an available slot, plugs itself in, then sets the callback:
void SignalMonitor::init() {
for (int i = 0; i < MAX_MONITORS; ++i) {
if (monitors[i] == NULL) {
callbackIndex = i;
monitors[i] = this;
break;
}
}
if (callbackIndex < 0)
throw "Maximum number of SignalMonitor instances reached";
wiringPiISR(dataPin, INT_EDGE_BOTH, smCallbacks[callbackIndex]);
}
There's also a destructor to free up the callback slots:
SignalMonitor::~SignalMonitor() {
if (callbackIndex >= 0)
monitors[callbackIndex] = NULL;
}
It may help to consider the traditional way of handling a similar issue. Other APIs have been designed where instead of void(*function)(void), wiringPiISR would expect a function void(*function)(void *). This allows the use of
static void signalHasChanged(void *p) {
static_cast<SignalMonitor*>(p)->signalHasChanged();
}
This is not a general solution, but because Raspberry Pi has a limited number of GPIO pins, and you can't have more callback functions than you have pins, you might be able to create one callback function per pin. Then, you need a global data structure that maps the interrupt pin to which SignalMonitor instance (or instances) it should signal. The constructor would register the 'this' object to a specific pin, then set the appropriate callback function based on the pin.
The callback functions would be able to pass a pin argument to a general function, which could then look up the specific SignalMonitor instance and call a class function.
I wouldn't want to do it for 1000 pins, 1000 instances, but this hack should work for anything running on a Pi.
I want to call the following function and pass it a function with a parameter. The purpose of that is that it should call the function with my specified parameter so I know what triggered the function (in that case a gpio pin on the Raspberry Pi).
int wiringPiISR( int pin, int edgeType, void (*function)( void ) );
Currently I have:
for ( int i = 0; i < myValues.size(); ++i )
{
int myValue = myValues[ i ];
wiringPiISR( myValue, INT_EDGE_RISING, &myCallback( myValue ) );
}
Though this is giving me the following error:
error: lvalue required as unary ‘&’ operand
Which I can't really understand as to my understanding, myValue is an lvalue or is it not?
Is it what I want do even possible? If so how?
The function wiringPiISR is from a library called wiringPi and I would like to avoid modifying it as much as possible.
You could combine the answers from imreal and Ryan Haining something like this.
std::function<void()> cbfunc;
void myCallback()
{
cbfunc();
}
void myWiringPiISR(int val, int mask, std::function<void()> callback)
{
cbfunc = callback;
wiringPiISR(val, mask, &myCallback);
}
... and then use it...
void myActualCallback(int v)
{
... do something...
}
myWiringPiISR(myValue, INT_EDGE_RISING, std::bind(myActualCallback, myValue));
No need to patch library, and you can use all the bind/function goodness. I'll leave you to find a way around the thread safety issues...
How does it work? Put simply 'std::bind' is binding together a function and it's parameters into a single std:function object which can then be 'called' from the myCallback function which acts as a shim around the callback that you pass. I'd given the callback function a confusing name before, but this edit has hopefully fixed that.
You can "vomit" the function. This doesn't require a user-defined mutable global variable and is thread-safe, unless you have a compiler that supports multiple threads but not per-thread exceptions which would be basically unusable.
myWiringPiISRWrapper(Value value, int edge, std::function<void()> func) {
try {
throw &func;
} catch(...) {
myWiringPiISR(value, edge, [] {
try {
throw;
} catch(std::function<void()>* func) {
(*func)();
}
});
}
}
It's disgusting and slow, but it's totally encapsulated which I think is a worthwhile upside. Note that this only works if the callback is never executed after the call to myWiringPiISR returns. In this case you can of course have a callback with whatever bound state you desire.
If myValue is something you can decide at compile time, you could set it statically and use an intermediate function to pass in.
void myCallbackHelper() {
static constexpr int myValue = 3;
myCallback(myValue);
}
wiringPiISR(myValue, INT_EDGE_RISING, &myCallbackHelper);
If you need to determine myValue at run time, you could still accomplish this, but not really thread-safely.
int& getMyValue() {
static int myValue;
return myValue;
}
void setMyValue(int i) {
getMyValue() = i;
}
void myCallbackHelper() {
myCallback(getMyValue());
}
Then set it and call
setMyValue(3);
wiringPiISR(myValue, INT_EDGE_RISING, &myCallbackHelper);
I looked up wiringPiISR and found that it is some sort of api call, so i am assuming you cannot change it.
Having said that, there is a reason most api-calls with a function-pointer-callback look sort of like this
void setCallback( void (*function)(void* data), void* userdata);
This allows people to cast their struct {blabla} data; to add some userdata, and when the function is called, it is passed along.
So basically, apart from hacking stuff with static variables, you can't pass any arguments.
You need to use std::function and std::bind.
Change your function signature to
int wiringPiISR (int pin, int edgeType, std::function<void()> func);
Inside you can call the callback simply using func()
And your call to:
int myValue = 3;
wiringPiISR(myValue, INT_EDGE_RISING, std::bind(myCallback, myValue));
What this does is create a std::function object (i.e. a callable) that wraps your function and keeps your desired value in its state.
This will only work on C++11 and newer.
If you have c++11, I suggest using std::function - it's quite a bit cleaner.
If not, your function signature is wrong. You want a callback with the type void(int) but your function takes a void()
Say that you define a callback function as such:
typedef std::function<void(float)> Callback;
And you have a function as such:
void ImAFunction(float a)
{
//Do something with a
}
Is there a way to be able to store a function without an argument then pass one to it at a later time?
Such as this:
//Define the Callback storage
Callback storage;
storage = std::bind(ImAFunction, this);
//Do some things
storage(5);
This wont work which I explain with some of my real code below.
I can get close to what I wan't if I bind the value in with the std::bind function. Such as:
//Change
//storage = std::bind(ImAFunction, this);
storage = std::bind(ImAFunction, this, 5.0); //5.0 is a float passed
This works but when I go to pass a value through the function the outcome is whatever I set it to before:
storage(100); //Output is still 5
I am basing the fact that I think this is possible on this article.
http://www.cprogramming.com/tutorial/function-pointers.html
It doesn't use the function or bind functions but it does pass pointer arguments and performs exactly what I need. The reason I don't just skip the bind function is because I am trying to store the function in a class (private) and I can't store it if it's a template because it's created with the class.
The error produced above comes from this code:
struct BindInfo {
Callback keyCallback;
int bindType;
bool isDown;
bool held;
std::string name;
};
template <class T1>
void bindEvent(int bindType, T1* keydownObj, void(T1::*keydownF)(float), std::string name)
{
BindInfo newKeyInfo = { std::bind(keydownF, keydownObj), bindType, false, false, name };
inputBindings.insert(std::pair<int, BindInfo>(BIND_NULL, newKeyInfo));
};
The error is:
No viable conversion from '__bind<void(Main::*&)(float), Main *&>' to 'Callback' (aka 'function<void (float)>'
Is this possible? Thanks in advance.
You can include a placeholder for an unbound argument:
std::bind(&Main::ImAFunction, this, std::placeholders::_1);
If you find that a bit of a mouthful, a lambda might be more readable:
[this](float a){ImAFunction(a);}
It sounds like what you're looking for is a function pointer. While I don't have a lot of experience using them in C++ I have used them in C so: Yes, it is possible. Perhaps something like this:
void (*IAmAFunctionPointer)(float) = &IAmAFunction;
The best way to think about that line is, that IAmAFunctionPointer is a pointer (hence the *), it returns a void, and takes a float. Then later:
float a = 5;
IAmAFunctionPointer(a);
You could even design it so that the callback function is passed into the method (I assume this is what you're looking for).
void DoStuffThenCallback(float a, void (*callback)(float))
{
//DoStuff
callback(a);
}
further reading: http://www.cprogramming.com/tutorial/function-pointers.html
I'm trying to store a callback in a class. Currently, I do something like this:
struct Callback {
Callback (std::function<void ()> func) : func_ (func){}
void call() const { func(); }
private:
std::function<void ()> func_;
};
As you can see, only a specific type of function (currently no return and no parameters) can be used.
Is there any way I could use such a class like this, where I pass it what to call it with?
void increment (int &n) {
++n;
}
int main() {
int someNum = 5;
Callback callback (increment, someNum); //will call `increment (someNum);`
}
I was thinking to use a parameter pack to store the arguments, and a typename to store the return type, and then making an std::function<ReturnType (Args)> callback_ sort of thing, and calling it with something like callback_ (givenArgs...);. I'm not really knowledgeable enough on templates to do this, however, or even figure out if it's possible.
The real use I'd be getting out of this (at least right now) is for a timer, but perhaps making a small generic_function<> class that wraps an std::function<> would help more. For this example, though, a timer that pauses and unpauses every 2 seconds:
void togglePause (Countdown &c) {
c.togglePause();
}
int main() {
Countdown main (10000); //create countdown of 10s
Countdown delay (2000, togglePause, main); //this one calls func when expired
for (; !main.expired();) { //go while unpaused time < 10s
delay.wait().reset(); //wait 2s, call callback, reset back to 2s
}
}
Of course this can be applied to other concepts as well, but I'm not sure how to go about attaining this syntax in the first place. I can build two different forms in case the return type is void just fine from an unrelated previous question, but storing a function with any number and types of arguments confuses me. If it's possible, how can I use syntax like this? If not, how close would the syntax be?
I think you just want to use std::bind to convert your function with an argument into a function taking no arguments:
int main() {
int someNum = 5;
std::function<void (void)> boundFunc = std::bind(increment, std::ref(someNum));
Callback callback (boundFunc); //will call `increment (someNum);`
}
Note that you need the std::ref to ensure that someNum is passed by reference and that you need to make sure that someNum stays in scope longer than the callback.
I was thinking about doing a take_timing function that would take the timing of any function passed to it. By any function it means that the arguments this callback takes is unknown by the caller. It would take too the arguments for the callback. But as it doesn't know how to call it, it would take another callback function, the caller of the callback, written by the function user. The stub would be something like this:
void take_timing(
void (*callback)(),
void (*caller(void (*callback)(),void* args_struct),
void* args_struct
)
{
// Start timer
caller(callback,args_struct);
// Stop timer, read timings, record...
}
void some_caller(void (*callback)(),void* args_struct)
{
// Cast "callback" to function signature
// Cast args_struct to some struct with args
// Call the callback with correct args signature
}
So comes my questions:
Is it possible?
Can it use variable arguments list to make it simples? How? I am helpless on this...
Is there a better way of doing it? Or is it just better to do a take_timing for every specific case?
Is there a OOP Design Pattern for this for use with C++?
I myself gave up on this, but put it here out of curiosity, maybe some very useful insights.
Just take a functor as a template argument. Something like:
template<typename F>
nanoseconds take_timing(F f) {
auto start = high_resolution_clock::now();
f();
auto end = high_resolution_clock::now();
return end - start;
}
long long factorial(int i);
take_timing( [](){factorial(20);} ); // wrap call to function taking arguments in zero-argument lambda
You're looking for varargs support, which does exist in ANSI C. A gazillion or so google hits will result if you search for it. Here's one at random: http://www.eskimo.com/~scs/cclass/int/sx11b.html
One way to handle this is to take a boost::bind function object as your parameter:
http://www.boost.org/doc/libs/1_48_0/libs/bind/bind.html
You could hide the fact that closures are involved with macros.