EDIT: Updated clean reproducible example.
I'm a beginner in C++ with a few years experience with C, so apologies if I am going about this the wrong way. I have tried to break down the issue to as small an example of code as I can. In my code I have inherited a C callback function and inside this I want to trigger another callback from a class member.
I am having two issues:
a) I don't have an instance of Range in Callback and the callback does not have a void * param for me to use.
b) I am getting an error message
error: invalid use of non-static data member ‘Range::cbk’
I'm just starting to learn C++ and the rules of OOP so apologies if I am doing things that are fundamentally flawed.
#include <iostream>
#include <functional>
class Range
{
public:
typedef std::function<void()> TCallback;
TCallback cbk;
Range()
{
cbk = std::bind(&Range::RunTest, this);
}
void Close() {}
~Range() { Close(); }
void RunTest()
{
std::cout << "RunningTest\n";
}
};
static void Callback(bool ev)
{
if (ev)
Range::cbk();
}
int main()
{
std::function<void(bool)> test;
Range r1;
test = std::bind(Callback, 1);
test(1);
return 0;
}
You can't call a member function without an instance.
You did it right in the Range constructor; you did it wrong in main and Callback.
static void Callback(Range* ptr, bool ev)
{
if (ev)
ptr->cbk();
}
And:
test = std::bind(Callback, &r1, 1);
// ^^^^^
If you can't change Callback, then what you want to do is simply impossible. You'd have to have some global Range pointer, but this is really minging. Ultimately it's why classes were invented but if you can't use them because you're stuck with a really flat C API then you just have to hack around it like you would in C.
Related
I have a bit of a design problem:
I have a class describing a Robot; It can move to different directions, move a camera to different views etc. It looks something like this:
class Robot {
private:
...
public:
void move_right();
void move_left();
void switch_camera()
void raise_camera()
}
I want to add another method which performs a series of events. Thing is, I need able to abort the events midway.
I do want to clarify that the robot is running on a micro controller and not on a standard OS - so I can't really send a signal to the process or anything.
My first idea was to store the event functions in an array and iterate over it:
#typedef void(robo_event *)(void)
robo_event next_event;
robo_event *event_sequence;
Robot() {
this->next_event = nullptr;
}
void perform_event_series() {
for(this->next_event = *event_sequence; this->next_event != nullptr; this->next_event+=sizeof(robo_event)) {
this->next_event();
}
}
void abort_event_series() {
this->next_event = nullptr;
}
Thing is, the c++ standard forbids storing addresses of member functions, so this is starting to get awkward. I can make the functions static, but I do need to use them quite frequently and that would still be awkward. I want to be able to change to event sequence without too much work if changes are yet to come, so I thought that saving those on some sort of array / vector would be the best.
Any help with c++ member function syntax / better ideas on how to approach this problem would be much appreciated.
Thing is, the c++ standard forbids storing addresses of member functions
C++ most certainly allows you to store pointers to member functions (and variables), but the syntax is a bit different to accommodate the this pointer type, virtual functions, inheritance, etc.
class Example
{
public:
double foo(int x) { return x * 1.5; }
};
int main() {
double (Example::* member_function_ptr)(int);
member_function_ptr = &Example::foo;
Example example;
std::cout << (example.*member_function_ptr)(2) << std::endl;
}
If all your functions are for the same class, same return type, same arguments, etc. then you can make a table of them easy enough.
Storing pointers to member functions is perfectly allowable in c++:
#include <vector>
class Robot {
private:
public:
void move_right();
void move_left();
void switch_camera();
void raise_camera();
};
struct Action
{
Action(void (Robot::*what)(void))
: what(what)
{}
void perform(Robot& who) const
{
(who.*what)();
}
void (Robot::*what)(void);
};
bool should_abort();
void perform_actions(Robot& who, std::vector<Action> const& actions)
{
for (auto&& action : actions)
{
if (should_abort()) break;
action.perform(who);
}
}
int main()
{
std::vector<Action> actions {
&Robot::move_right,
&Robot::raise_camera,
&Robot::switch_camera,
&Robot::move_left
};
Robot r;
perform_actions(r, actions);
}
Pointers to functions are of different types to pointers to members.
You need void(Robot::*)(void) not void(*)(void).
class Robot {
private:
typedef void(Robot::*robot_event)(void)
robo_event next_event;
robo_event *event_sequence;
Robot() {
next_event = nullptr;
}
void perform_event_series() {
for(next_event = *event_sequence; next_event != nullptr; ++next_event) {
(this->*next_event)();
}
}
void abort_event_series() {
next_event = nullptr;
}
public:
void move_right();
void move_left();
void switch_camera()
void raise_camera()
}
The Settings: I'm building an architecture that has parts in C and part in C++.
In my Architecture I have:
A data_io(C) which gets data sends it to a processor callback and outputs the processed data.
A data_processor(C) which takes care of processing data and changes on-demand.
A settings_manager(C++) which decides which processor to use.
The relationship is as follows:
The settings_manager object is instantiated, inside it initializes the data_processor with a default processor function, and then initializes the data_io sending to it a processing_callback_function (defined in the settings_manager, but internally referencing a data_processor function) which is then used to process the data when the data_io starts. (so, the data_io receives the processing_callback_function only once at initialization and does not care about what the callback does inside, it just generates data, calls the processing_callback_function and outputs processed data)
While the system is working, the settings_manager may decide to change the data_processor type of processing, so it changes the processing_callback_function to call a different data_processor function.(the data_io does not know about it and continues working)
Here is the basic implementation:
data_io.c:
typedef void (* ProcessorCallback_t)(float *, int);
ProcessorCallback_t processorCallback;
data_io_init(ProcessorCallback_t callback) {
processorCallback;
...init all other stuff like data pointer...
}
data_io_loop() {
bufSize = readData(&data);
processorCallback(&data, bufSize);
writeData(&data, bufSize);
}
data_procesor.c:
void data_processor_init() {
...initialization routine...
}
void data_processor_proc1(float *data, int bufSize) {
...data process...
}
void data_processor_proc2(float *data, int bufSize) {
...data process...
}
settings_manager.cpp:
void SettingsManager::start() {
data_processor_init();
this->processing_function = &data_processor_proc1;
//THIS IS MY QUESTION! HOW TO PASS THE processing_callback_function TO data_io_init
data_io_init(&SettingsManager::processing_callback_function);
... here starts a new thread to run loop below...
//while(this->condition) {
// data_io_loop();
//}
}
void SettingsManager::changeProcessorType(int processorType) {
switch(processorType) {
case 1:
this->processing_function = &data_processor_proc1;
break;
case 2:
this->processing_function = &data_processor_proc2;
break;
}
}
void SettingsManager::processing_callback_function(float *data, int buffer_size) {
this->processing_function(data, buffer_size);
}
My Questions:
1. How should I pass the processing_callback_function C++ member function to the data_io_init C function?
when I do the following:
data_io_init(&SettingsManager::processing_callback_function);
I get the following error:
"Incompatible pointer types 'ProcessorCallback_t' and 'void(Engine::*)(float*,int)'"
Well the error is obvious, the types are different as the second is a member function and is part of the instance of the object.
I've read that I should make the processing_callback_function static, but I'm not sure if it is the right approach.
What is the appropriate way to handle this kind of things, are there any patrons that might be useful to read, or coding strategies that may be related?
A non-static class method has a hidden this pointer that a free-standing function does not. So such, you can't pass a non-static class method where a free-standing function is expected.
The best solution in this situation is to allow the C++ code to pass a user-defined value to the C code, and then have the C code passes that value back to the C++ code. That way, the C++ code can pass around its this pointer. For example:
data_io.h:
typedef void (* ProcessorCallback_t)(float *, int, void *);
void data_io_init(ProcessorCallback_t callback, void *userdata);
void data_io_loop();
data_io.c:
ProcessorCallback_t processorCallback;
void *processorUserData;
void data_io_init(ProcessorCallback_t callback, void *userdata) {
processorCallback = callback;
processorUserData = userdata;
...init other stuff as needed ...
}
void data_io_loop() {
...
processorCallback(&data, bufSize, processorUserData);
...
}
Then SettingsManager can do this:
settings_manager.h:
typedef void (* ProcessorFunc_t)(float *, int);
class SettingsManager
{
private:
ProcessorFunc_t processing_function;
...
static void processing_callback_function(float *data, int buffer_size void *userdata);
public:
void start();
...
};
settings_manager.cpp:
#include "data_io.h"
void SettingsManager::start()
{
...
data_io_init(&SettingsManager::processing_callback_function, this);
...
}
void SettingsManager::processing_callback_function(float *data, int buffer_size void *userdata)
{
static_cast<SettingsManager*>(userdata)->processing_function(data, buffer_size);
}
Or this (as the above is technically undefined behavior, but it does work in most compilers. The below is more standards compliant):
settings_manager.h:
typedef void (* ProcessorFunc_t)(float *, int);
class SettingsManager
{
...
public:
ProcessorFunc_t processing_function;
void start();
...
};
settings_manager.cpp:
#include "data_io.h"
void processing_callback_function(float *data, int buffer_size void *userdata)
{
static_cast<SettingsManager*>(userdata)->processing_function(data, buffer_size);
}
void SettingsManager::start()
{
...
data_io_init(&processing_callback_function, this);
...
}
1) Write everything in C++. Use std::function as a callback. This is the best way to handle this. Do you really have a performance issue? Have you measured it? C++ is not that slow. Problems that you will have by mixing two lanuage styles will bring more problems.
2) Functions are the same in C and C++. You can always do the following:
class Cls {
public:
void callback() {}
};
void Cls_callback(void* ptr) {
reinterpret_cast<Cls*>(ptr)->callback();
}
And then pass that Cls_callback as the C callback.
3) You may make Cls_callback a static method of Cls and that way it will have access to private members of Cls:
class Cls {
public:
static void Cls_callback(void* ptr) {
Cls* self = reinterpret_cast<Cls*>(ptr);
self->i += 1;
}
private:
int i;
};
But keep in mind, that this actually is an UB. It will work, it is slightly less code than variant 2, but technically speaking, standard does not guarantee that this will work.
P.S. Yet again, don't mix styles. Use C++ everywhere.
I have to make some kind of bridge between two pieces of software, but am facing an issue I don't know how to deal with. Hopefully someone will have interesting and (preferably) working suggestions.
Here is the background : I have a C++ software suite. I have to replace some function within a given class with another function, which is ok. The problem is that the new function calls another function which has to be static, but has to deal with members of the class. This is this second function which is making me mad.
If the function is not static I get the following error :
error: argument of type ‘void (MyClass::)(…)’ does not match ‘void (*)(…)’
If I set it to static I get either the following error :
error: cannot call member function ‘void
MyClass::MyFunction(const double *)’ without object
or
error: ‘this’ is unavailable for static member functions
depending on if I use or not the "this" keyword ("Function()" or "this->Function()").
And finally, the class object requires some arguments which I cannot pass to the static function (I cannot modify the static function prototype), which prevents me to create a new instance within the static function itself.
How would you deal with such a case with minimal rewriting ?
Edit : Ok, here is a simplified sample on what I have to do, hoping it is clear and correct :
// This function is called by another class on an instance of MyClass
MyClass::BigFunction()
{
…
// Call of a function from an external piece of code,
// which prototype I cannot change
XFunction(fcn, some more args);
…
}
// This function has to be static and I cannot change its prototype,
// for it to be passed to XFunction. XFunction makes iterations on it
// changing parameters (likelihood maximization) which do not appear
// on this sample
void MyClass::fcn(some args, typeN& result)
{
// doesn't work because fcn is static
result = SomeComputation();
// doesn't work, for the same reason
result = this->SomeComputation();
// doesn't work either, because MyClass has many parameters
// which have to be set
MyClass *tmp = new MyClass();
result = tmp->SomeComputation();
}
Pointers to non-static member functions are a bit tricky to deal with. The simplest workaround would just be to add an opaque pointer argument to your function which you can then cast as a pointer to 'this', then do what you need with it.
Here's a very simple example:
void doSomething(int (*callback)(void *usrPtr), void *usrPtr)
{
// Do stuff...
int value = callback(usrPtr);
cout << value << "\n";
}
class MyClass
{
public:
void things()
{
value_ = 42;
doSomething(myCallback, this);
}
private:
int value_;
static int myCallback(void *usrPtr)
{
MyClass *parent = static_cast<MyClass *>(usrPtr);
return parent->value_;
}
};
int main()
{
MyClass object;
object.things();
return 0;
}
In this example myCallback() can access the private value_ through the opaque pointer.
If you want a more C++-like approach you could look into using Boost.Function and Boost.Bind which allow you to pass non-static member functions as callbacks:
void doSomething(boost::function<int ()> callback)
{
// Do stuff...
int value = callback();
cout << value << "\n";
}
class MyClass
{
public:
void things()
{
value_ = 42;
doSomething(boost::bind(&MyClass::myCallback, this));
}
private:
int value_;
int myCallback()
{
return value_;
}
};
int main()
{
MyClass object;
object.things();
return 0;
}
If you really can't change the function prototype you could use a global pointer, but that opens up all sorts of issues if you will ever have more than one instance of your class. It's just generally bad practice.
class MyClass;
static MyClass *myClass;
void doSomething(int (*callback)())
{
// Do stuff...
int value = callback();
cout << value << "\n";
}
class MyClass
{
public:
void things()
{
value_ = 42;
myClass = this;
doSomething(myCallback);
}
private:
int value_;
static int myCallback()
{
return myClass->value_;
}
};
int main()
{
MyClass object;
object.things();
return 0;
}
Following spencercw's suggestion below the initial question I tried the "static member variable that you set to point to this" solution (the global variable would have been tricky and dangerous within the context of the software suite).
Actually I figured out there was already something like this implemented in the code (which I didn't write) :
static void* currentObject;
So I just used it, as
((MyClass*)currentObject)->SomeComputation();
It does work, thanks !!!
non-reentrant and non-thread-safe way is to pass "this" address using global variable.
You can move the result = SomeComputation(); out of your static function and place it in BigFunction right before your call to the static function.
Suppose I have a class with 2 static functions:
class CommandHandler
{
public:
static void command_one(Item);
static void command_two(Item);
};
I have a DRY problem where I have 2 functions that have the exact same code for every single line, except for the function that it calls:
void CommandOne_User()
{
// some code A
CommandHandler::command_one(item);
// some code B
}
void CommandTwo_User()
{
// some code A
CommandHandler::command_two(item);
// some code B
}
I would like to remove duplication, and, ideally, do something like this:
void CommandOne_User()
{
Function func = CommandHandler::command_one();
Refactored_CommandUser(func);
}
void CommandTwo_User()
{
Function func = CommandHandler::command_one();
Refactored_CommandUser(func);
}
void Refactored_CommandUser(Function func)
{
// some code A
func(item);
}
I have access to Qt, but not Boost. Could someone help suggest a way on how I can refactor something like this?
You could use function pointers:
// type of the functions
typedef void Function(Item);
void CommandOne_User() {
// function pointer
Function *func = CommandHandler::command_one;
Refactored_CommandUser(func);
}
void CommandTwo_User() {
// can also be used directly, without a intermediate variable
Refactored_CommandUser(CommandHandler::command_two);
}
// taking a function pointer for the command that should be executed
void Refactored_CommandUser(Function *func) {
// calling the funcion (no explicit dereferencing needed, this conversion is
// done automatically)
func(item);
}
Besides the C way (passing a function pointer) or the C++ way mentioned by Jay here there is the other (modern) c++ way with boost or with a compiler with c++0x support:
void Refactored_CommandUser( boost::function<void (Item)> f ) {
// alternatively std::function with proper compiler support
}
With the advantage that this encapsulates a functor, and can be combined with boost::bind (or std::bind) to pass in not only free-function pointers that match the signature exactly, but also other things, like member pointers with an object:
struct test {
void f( Item );
};
void foo( Item i, std::string const & caller );
void bar( Item i );
int main() {
test t;
Refactored_CommandUser( boost::bind( &test::f, &t, _1 ) );
Refactored_CommandUser( boost::bind( foo, _1, "main" ) );
Refactored_CommandUser( bar ); // of course you can pass a function that matches directly
}
I posted a question very similar to this and this was the explanation I got:
Function Pointers
And here is the link to the question I posted: Function callers (callbacks) in C?
Another way to do this if you don't have access to tr1 or boost, is just to use function template. It's quite simple and obviously a C++ way.
Here's a compilable example similar to yours:
#include <iostream>
using namespace std;
class CommandHandler
{
public:
static void command_one(int i) { cout << "command_one " << i << endl; }
static void command_two(int i) { cout << "command_two " << i << endl; }
};
template <typename Func>
void CommandCaller(Func f)
{
f(1);
}
int main()
{
CommandCaller(&CommandHandler::command_one);
return 0;
}
I can think of two ways.
The C style way: pass the function to be called in as a function pointer.
The C++ way: create a base class that implements your code and replace the called function with a virtual method. Then derive two concrete classes from the base class, each one implementing the virtual function differently.
see this please
http://www.newty.de/fpt/fpt.html
Static member functions can be passed simply as function pointers.
Non-static can be passed as member-function pointer + this.
void Refactored_CommandUser(static void (*func)(Item))
{
// some code A
func(item);
// some code B
}
void CommandOne_User()
{
Refactored_CommandUser(&CommandHandler::command_one);
}
void CommandTwo_User()
{
Refactored_CommandUser(&CommandHandler::command_two);
}
So inspired by David Roriguez's answer, I tried it out on my own and, yup, it works:
Here's an example (stupid) code of the "modern" way to pass a function as a function parameter:
#include <functional>
#include <assert.h>
class Command
{
public:
static int getSeven(int number_)
{
return 7 + number_;
}
static int getEight(int number_)
{
return 8 - number_;
}
};
int func(std::tr1::function<int (int)> f, int const number_ )
{
int const new_number = number_ * 2;
int const mod_number = f(new_number);
return mod_number - 3;
}
int main()
{
assert( func(Command::getSeven, 5) == 14 );
assert( func(Command::getEight, 10) == -15 );
return 0;
}
I tried this on VS2008 with Intel C++ Compiler 11.1 with C++0X support on (don't know if C++0x support is really needed since it's in TR1).
I need to bind a method into a function-callback, except this snippet is not legal as discussed in demote-boostfunction-to-a-plain-function-pointer.
What's the simplest way to get this behavior?
struct C {
void m(int x) {
(void) x;
_asm int 3;
}};
typedef void (*cb_t)(int);
int main() {
C c;
boost::function<void (int x)> cb = boost::bind(&C::m, &c, _1);
cb_t raw_cb = *cb.target<cb_t>(); //null dereference
raw_cb(1);
return 0;
}
You can make your own class to do the same thing as the boost bind function. All the class has to do is accept the function type and a pointer to the object that contains the function. For example, this is a void return and void param delegate:
template<typename owner>
class VoidDelegate : public IDelegate
{
public:
VoidDelegate(void (owner::*aFunc)(void), owner* aOwner)
{
mFunction = aFunc;
mOwner = aOwner;
}
~VoidDelegate(void)
{}
void Invoke(void)
{
if(mFunction != 0)
{
(mOwner->*mFunction)();
}
}
private:
void (owner::*mFunction)(void);
owner* mOwner;
};
Usage:
class C
{
void CallMe(void)
{
std::cout << "called";
}
};
int main(int aArgc, char** aArgv)
{
C c;
VoidDelegate<C> delegate(&C::CallMe, &c);
delegate.Invoke();
}
Now, since VoidDelegate<C> is a type, having a collection of these might not be practical, because what if the list was to contain functions of class B too? It couldn't.
This is where polymorphism comes into play. You can create an interface IDelegate, which has a function Invoke:
class IDelegate
{
virtual ~IDelegate(void) { }
virtual void Invoke(void) = 0;
}
If VoidDelegate<T> implements IDelegate you could have a collection of IDelegates and therefore have callbacks to methods in different class types.
Either you can shove that bound parameter into a global variable and create a static function that can pick up the value and call the function on it, or you're going to have to generate per-instance functions on the fly - this will involve some kind of on the fly code-gen to generate a stub function on the heap that has a static local variable set to the value you want, and then calls the function on it.
The first way is simple and easy to understand, but not at all thread-safe or reentrant. The second version is messy and difficult, but thread-safe and reentrant if done right.
Edit: I just found out that ATL uses the code generation technique to do exactly this - they generate thunks on the fly that set up the this pointer and other data and then jump to the call back function. Here's a CodeProject article that explains how that works and might give you an idea of how to do it yourself. Particularly look at the last sample (Program 77).
Note that since the article was written DEP has come into existance and you'll need to use VirtualAlloc with PAGE_EXECUTE_READWRITE to get a chunk of memory where you can allocate your thunks and execute them.
#include <iostream>
typedef void(*callback_t)(int);
template< typename Class, void (Class::*Method_Pointer)(void) >
void wrapper( int class_pointer )
{
Class * const self = (Class*)(void*)class_pointer;
(self->*Method_Pointer)();
}
class A
{
public:
int m_i;
void callback( )
{ std::cout << "callback: " << m_i << std::endl; }
};
int main()
{
A a = { 10 };
callback_t cb = &wrapper<A,&A::callback>;
cb( (int)(void*)&a);
}
i have it working right now by turning C into a singleton, factoring C::m into C::m_Impl, and declaring static C::m(int) which forwards to the singleton instance. talk about a hack.