Why would one use function pointers to member method in C++? - c++

A lot of C++ books and tutorials explain how to do this, but I haven't seen one that gives a convincing reason to choose to do this.
I understand very well why function pointers were necessary in C (e.g., when using some POSIX facilities). However, AFAIK you can't send them a member function because of the "this" parameter. But if you're already using classes and objects, why not just use an object oriented solution like functors?
Real world examples of where you had to use such function pointers would be appreciated.
Update: I appreciate everyone's answers. I have to say, though, that none of these examples really convinces me that this is a valid mechanism from a pure-OO perspective...

Functors are not a priori object-oriented (in C++, the term “functor” usually means a struct defining an operator () with arbitrary arguments and return value that can be used as syntactical drop-in replacements to real functions or function pointers). However, their object-oriented problem has a lot of issues, first and foremost usability. It's just a whole lot of complicated boilerplate code. In order for a decent signalling framework as in most dialog frameworks, a whole lot of inheritance mess becomes necessary.
Instance-bound function pointers would be very beneficial here (.NET demonstrates this amply with delegates).
However, C++ member function pointers satisfy another need still. Imagine, for example, that you've got a lot of values in a list of which you want to execute one method, say its print(). A function pointer to YourType::size helps here because it lets you write such code:
std::for_each(lst.begin(), lst.end(), std::mem_fun(&YourType::print))

In the past, member function pointers used to be useful in scenarios like this:
class Image {
// avoid duplicating the loop code
void each(void(Image::* callback)(Point)) {
for(int x = 0; x < w; x++)
for(int y = 0; y < h; y++)
callback(Point(x, y));
}
void applyGreyscale() { each(&Image::greyscalePixel); }
void greyscalePixel(Point p) {
Color c = pixels[p];
pixels[p] = Color::fromHsv(0, 0, (c.r() + c.g() + c.b()) / 3);
}
void applyInvert() { each(&Image::invertPixel); }
void invertPixel(Point p) {
Color c = pixels[p];
pixels[p] = Color::fromRgb(255 - c.r(), 255 - r.g(), 255 - r.b());
}
};
I've seen that used in a commercial painting app. (interestingly, it's one of the few C++ problems better solved with the preprocessor).
Today, however, the only use for member function pointers is inside the implementation of boost::bind.

Here is a typical scenario we have here. We have a notification framework, where a class can register to multiple different notifications. When registering to a notification, we pass the member function pointer. This is actually very similar to C# events.
class MyClass
{
MyClass()
{
NotificationMgr::Register( FunctionPtr( this, OnNotification ) );
}
~MyClass()
{
NotificationMgr::UnRegister( FunctionPtr( this, OnNotification ) );
}
void OnNotification( ... )
{
// handle notification
}
};

I have some code I'm working on right now where I used them to implement a state machine. The dereferenced member functions implement the states, but since they are all in the class they get to share a certian amount of data that is global to the entire state machine. That would have been tough to accomplish with normal (non-member) function pointers.
I'm still undecided on if this is a good way to implement a state machine though.

It is like using lambdas. You always can pass all necessary local variables to a simple function, but sometimes you have to pass more then one of them.
So using member functions will save you from passing all necessary member fields to a functor. That's all.

You asked specifically about member functions, but there are other uses for function pointers as well. The most common reason why I need to use function pointers in C++ is when I want to load a DLL ar runtime using LoadLibrary(). This is in Windows, obviously. In applications that use plugins in the form of optional DLLs, dynamic linking can't be used at application startup since the DLL will often not be present, and using delayload is a pain.
After loading the library, you have to get a pointer to the functions you want to use.

I have used member function pointers parsing a file. Depending on specific strings found in the file the same value was found in a map and the associated function called. This was instead of a large if..else if..else statement comparing strings.

The single most important use of member pointers is creating functors. The good news is that you hardly even need to use it directly, as it is already solved in libraries as boost::bind, but you do have to pass the pointers to those libs.
class Processor
{
public:
void operation( int value );
void another_operation( int value );
};
int main()
{
Processor tc;
boost::thread thr1( boost::bind( &Processor::operation, &tc, 100 ) );
boost::thread thr2( boost::bind( &Processor::another_operation, &tc, 5 ) );
thr1.join();
thr2.join();
}
You can see the simplicity of creating a thread that executes a given operation on a given instance of a class.
The simple handmade approach to the problem above would be on the line of creating a functor yourself:
class functor1
{
public:
functor1( Processor& o, int v ) : o_(o), v_(v) {}
void operator()() {
o_.operation( v_ ); // [1]
}
private:
Processor& o_;
int v_;
};
and create a different one for each member function you wish to call. Note that the functor is exactly the same for operation and for another_operation, but the call in [1] would have to be replicated in both functors. Using a member function pointer you can write a simple functor:
class functor
{
public:
functor( void (*Processor::member)(int), Processor& p, int value )
: member_( member ), processor_(p), value_( value ) {}
void operator()() {
p.*member(value_);
}
private:
void (*Processor::member_)(int);
Processor& processor_;
int value;
};
and use it:
int main() {
Processor p;
boost::thread thr1( functor( &Processor::operation, p, 100 ) );
boost::thread thr2( functor( &Processor::another_operation, p, 5 ) );
thr1.join();
thr2.join();
}
Then again, you don't need to even define that functor as boost::bind does it for you. The upcoming standard will have its own version of bind along the lines of boost's implementation.

A pointer to a member function is object-agnostic. You need it if you want to refer to a function by value at run-time (or as a template parameter). It comes into its own when you don't have a single object in mind upon which to call it.
So if you know the function, but don't know the object AND you wish to pass this knowledge by value, then point-to-member-function is the only prescribed solution. Iraimbilanja's example illustrates this well. It may help you to see my example use of a member variable. The principle is the same.

I used a function pointer to a member function in a scenario where I had to provide a function pointer to a callback with a predefined parameter list (so I couldn't pass arbitrary parameters) to some 3rd-party API object.
I could not implement the callback in the global namespace because it was supposed to handle incoming events based on state of the object which made use of the 3rd party API which had triggered the callback.
So I wanted the implementation of the callback to be part of the class which made use of the 3rd-party object. What I did is, I declared a public and static member function in the class I wanted to implement the callback in and passed a pointer to it to the API object (the static keyword sparing me the this pointer trouble).
The this pointer of my object would then be passed as part of the Refcon for the callback (which luckily contained a general purpose void*).
The implementation of the dummy then used the passed pointer to invoke the actual, and private, implementation of the callback contained in the class = ).
It looked something like this:
public:
void SomeClass::DummyCallback( void* pRefCon ) [ static ]
{
reinterpret_cast<SomeClassT*>(pRefCon)->Callback();
}
private:
void class SomeClass::Callback() [ static ]
{
// some code ...
}

Related

Windows C++: How can I define a callback member function of type WINAPI? [duplicate]

I'm using an API that requires me to pass a function pointer as a callback. I'm trying to use this API from my class but I'm getting compilation errors.
Here is what I did from my constructor:
m_cRedundencyManager->Init(this->RedundencyManagerCallBack);
This doesn't compile - I get the following error:
Error 8 error C3867: 'CLoggersInfra::RedundencyManagerCallBack': function call missing argument list; use '&CLoggersInfra::RedundencyManagerCallBack' to create a pointer to member
I tried the suggestion to use &CLoggersInfra::RedundencyManagerCallBack - didn't work for me.
Any suggestions/explanation for this??
I'm using VS2008.
Thanks!!
This is a simple question but the answer is surprisingly complex. The short answer is you can do what you're trying to do with std::bind1st or boost::bind. The longer answer is below.
The compiler is correct to suggest you use &CLoggersInfra::RedundencyManagerCallBack. First, if RedundencyManagerCallBack is a member function, the function itself doesn't belong to any particular instance of the class CLoggersInfra. It belongs to the class itself. If you've ever called a static class function before, you may have noticed you use the same SomeClass::SomeMemberFunction syntax. Since the function itself is 'static' in the sense that it belongs to the class rather than a particular instance, you use the same syntax. The '&' is necessary because technically speaking you don't pass functions directly -- functions are not real objects in C++. Instead you're technically passing the memory address for the function, that is, a pointer to where the function's instructions begin in memory. The consequence is the same though, you're effectively 'passing a function' as a parameter.
But that's only half the problem in this instance. As I said, RedundencyManagerCallBack the function doesn't 'belong' to any particular instance. But it sounds like you want to pass it as a callback with a particular instance in mind. To understand how to do this you need to understand what member functions really are: regular not-defined-in-any-class functions with an extra hidden parameter.
For example:
class A {
public:
A() : data(0) {}
void foo(int addToData) { this->data += addToData; }
int data;
};
...
A an_a_object;
an_a_object.foo(5);
A::foo(&an_a_object, 5); // This is the same as the line above!
std::cout << an_a_object.data; // Prints 10!
How many parameters does A::foo take? Normally we would say 1. But under the hood, foo really takes 2. Looking at A::foo's definition, it needs a specific instance of A in order for the 'this' pointer to be meaningful (the compiler needs to know what 'this' is). The way you usually specify what you want 'this' to be is through the syntax MyObject.MyMemberFunction(). But this is just syntactic sugar for passing the address of MyObject as the first parameter to MyMemberFunction. Similarly, when we declare member functions inside class definitions we don't put 'this' in the parameter list, but this is just a gift from the language designers to save typing. Instead you have to specify that a member function is static to opt out of it automatically getting the extra 'this' parameter. If the C++ compiler translated the above example to C code (the original C++ compiler actually worked that way), it would probably write something like this:
struct A {
int data;
};
void a_init(A* to_init)
{
to_init->data = 0;
}
void a_foo(A* this, int addToData)
{
this->data += addToData;
}
...
A an_a_object;
a_init(0); // Before constructor call was implicit
a_foo(&an_a_object, 5); // Used to be an_a_object.foo(5);
Returning to your example, there is now an obvious problem. 'Init' wants a pointer to a function that takes one parameter. But &CLoggersInfra::RedundencyManagerCallBack is a pointer to a function that takes two parameters, it's normal parameter and the secret 'this' parameter. That's why you're still getting a compiler error (as a side note: If you've ever used Python, this kind of confusion is why a 'self' parameter is required for all member functions).
The verbose way to handle this is to create a special object that holds a pointer to the instance you want and has a member function called something like 'run' or 'execute' (or overloads the '()' operator) that takes the parameters for the member function, and simply calls the member function with those parameters on the stored instance. But this would require you to change 'Init' to take your special object rather than a raw function pointer, and it sounds like Init is someone else's code. And making a special class for every time this problem comes up will lead to code bloat.
So now, finally, the good solution, boost::bind and boost::function, the documentation for each you can find here:
boost::bind docs,
boost::function docs
boost::bind will let you take a function, and a parameter to that function, and make a new function where that parameter is 'locked' in place. So if I have a function that adds two integers, I can use boost::bind to make a new function where one of the parameters is locked to say 5. This new function will only take one integer parameter, and will always add 5 specifically to it. Using this technique, you can 'lock in' the hidden 'this' parameter to be a particular class instance, and generate a new function that only takes one parameter, just like you want (note that the hidden parameter is always the first parameter, and the normal parameters come in order after it). Look at the boost::bind docs for examples, they even specifically discuss using it for member functions. Technically there is a standard function called [std::bind1st][3] that you could use as well, but boost::bind is more general.
Of course, there's just one more catch. boost::bind will make a nice boost::function for you, but this is still technically not a raw function pointer like Init probably wants. Thankfully, boost provides a way to convert boost::function's to raw pointers, as documented on StackOverflow here. How it implements this is beyond the scope of this answer, though it's interesting too.
Don't worry if this seems ludicrously hard -- your question intersects several of C++'s darker corners, and boost::bind is incredibly useful once you learn it.
C++11 update: Instead of boost::bind you can now use a lambda function that captures 'this'. This is basically having the compiler generate the same thing for you.
That doesn't work because a member function pointer cannot be handled like a normal function pointer, because it expects a "this" object argument.
Instead you can pass a static member function as follows, which are like normal non-member functions in this regard:
m_cRedundencyManager->Init(&CLoggersInfra::Callback, this);
The function can be defined as follows
static void Callback(int other_arg, void * this_pointer) {
CLoggersInfra * self = static_cast<CLoggersInfra*>(this_pointer);
self->RedundencyManagerCallBack(other_arg);
}
This answer is a reply to a comment above and does not work with VisualStudio 2008 but should be preferred with more recent compilers.
Meanwhile you don't have to use a void pointer anymore and there is also no need for boost since std::bind and std::function are available. One advantage (in comparison to void pointers) is type safety since the return type and the arguments are explicitly stated using std::function:
// std::function<return_type(list of argument_type(s))>
void Init(std::function<void(void)> f);
Then you can create the function pointer with std::bind and pass it to Init:
auto cLoggersInfraInstance = CLoggersInfra();
auto callback = std::bind(&CLoggersInfra::RedundencyManagerCallBack, cLoggersInfraInstance);
Init(callback);
Complete example for using std::bind with member, static members and non member functions:
#include <functional>
#include <iostream>
#include <string>
class RedundencyManager // incl. Typo ;-)
{
public:
// std::function<return_type(list of argument_type(s))>
std::string Init(std::function<std::string(void)> f)
{
return f();
}
};
class CLoggersInfra
{
private:
std::string member = "Hello from non static member callback!";
public:
static std::string RedundencyManagerCallBack()
{
return "Hello from static member callback!";
}
std::string NonStaticRedundencyManagerCallBack()
{
return member;
}
};
std::string NonMemberCallBack()
{
return "Hello from non member function!";
}
int main()
{
auto instance = RedundencyManager();
auto callback1 = std::bind(&NonMemberCallBack);
std::cout << instance.Init(callback1) << "\n";
// Similar to non member function.
auto callback2 = std::bind(&CLoggersInfra::RedundencyManagerCallBack);
std::cout << instance.Init(callback2) << "\n";
// Class instance is passed to std::bind as second argument.
// (heed that I call the constructor of CLoggersInfra)
auto callback3 = std::bind(&CLoggersInfra::NonStaticRedundencyManagerCallBack,
CLoggersInfra());
std::cout << instance.Init(callback3) << "\n";
}
Possible output:
Hello from non member function!
Hello from static member callback!
Hello from non static member callback!
Furthermore using std::placeholders you can dynamically pass arguments to the callback (e.g. this enables the usage of return f("MyString"); in Init if f has a string parameter).
What argument does Init take? What is the new error message?
Method pointers in C++ are a bit difficult to use. Besides the method pointer itself, you also need to provide an instance pointer (in your case this). Maybe Init expects it as a separate argument?
A pointer to a class member function is not the same as a pointer to a function. A class member takes an implicit extra argument (the this pointer), and uses a different calling convention.
If your API expects a nonmember callback function, that's what you have to pass to it.
Is m_cRedundencyManager able to use member functions? Most callbacks are set up to use regular functions or static member functions. Take a look at this page at C++ FAQ Lite for more information.
Update: The function declaration you provided shows that m_cRedundencyManager is expecting a function of the form: void yourCallbackFunction(int, void *). Member functions are therefore unacceptable as callbacks in this case. A static member function may work, but if that is unacceptable in your case, the following code would also work. Note that it uses an evil cast from void *.
// in your CLoggersInfra constructor:
m_cRedundencyManager->Init(myRedundencyManagerCallBackHandler, this);
// in your CLoggersInfra header:
void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr);
// in your CLoggersInfra source file:
void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr)
{
((CLoggersInfra *)CLoggersInfraPtr)->RedundencyManagerCallBack(i);
}
Necromancing.
I think the answers to date are a little unclear.
Let's make an example:
Supposed you have an array of pixels (array of ARGB int8_t values)
// A RGB image
int8_t* pixels = new int8_t[1024*768*4];
Now you want to generate a PNG.
To do so, you call the function toJpeg
bool ok = toJpeg(writeByte, pixels, width, height);
where writeByte is a callback-function
void writeByte(unsigned char oneByte)
{
fputc(oneByte, output);
}
The problem here: FILE* output has to be a global variable.
Very bad if you're in a multithreaded environment (e.g. a http-server).
So you need some way to make output a non-global variable, while retaining the callback signature.
The immediate solution that springs into mind is a closure, which we can emulate using a class with a member function.
class BadIdea {
private:
FILE* m_stream;
public:
BadIdea(FILE* stream) {
this->m_stream = stream;
}
void writeByte(unsigned char oneByte){
fputc(oneByte, this->m_stream);
}
};
And then do
FILE *fp = fopen(filename, "wb");
BadIdea* foobar = new BadIdea(fp);
bool ok = TooJpeg::writeJpeg(foobar->writeByte, image, width, height);
delete foobar;
fflush(fp);
fclose(fp);
However, contrary to expectations, this does not work.
The reason is, C++ member functions are kinda implemented like C# extension functions.
So you have
class/struct BadIdea
{
FILE* m_stream;
}
and
static class BadIdeaExtensions
{
public static writeByte(this BadIdea instance, unsigned char oneByte)
{
fputc(oneByte, instance->m_stream);
}
}
So when you want to call writeByte, you need pass not only the address of writeByte, but also the address of the BadIdea-instance.
So when you have a typedef for the writeByte procedure, and it looks like this
typedef void (*WRITE_ONE_BYTE)(unsigned char);
And you have a writeJpeg signature that looks like this
bool writeJpeg(WRITE_ONE_BYTE output, uint8_t* pixels, uint32_t
width, uint32_t height))
{ ... }
it's fundamentally impossible to pass a two-address member function to a one-address function pointer (without modifying writeJpeg), and there's no way around it.
The next best thing that you can do in C++, is using a lambda-function:
FILE *fp = fopen(filename, "wb");
auto lambda = [fp](unsigned char oneByte) { fputc(oneByte, fp); };
bool ok = TooJpeg::writeJpeg(lambda, image, width, height);
However, because lambda is doing nothing different, than passing an instance to a hidden class (such as the "BadIdea"-class), you need to modify the signature of writeJpeg.
The advantage of lambda over a manual class, is that you just need to change one typedef
typedef void (*WRITE_ONE_BYTE)(unsigned char);
to
using WRITE_ONE_BYTE = std::function<void(unsigned char)>;
And then you can leave everything else untouched.
You could also use std::bind
auto f = std::bind(&BadIdea::writeByte, &foobar);
But this, behind the scene, just creates a lambda function, which then also needs the change in typedef.
So no, there is no way to pass a member function to a method that requires a static function-pointer.
But lambdas are the easy way around, provided that you have control over the source.
Otherwise, you're out of luck.
There's nothing you can do with C++.
Note:
std::function requires #include <functional>
However, since C++ allows you to use C as well, you can do this with libffcall in plain C, if you don't mind linking a dependency.
Download libffcall from GNU (at least on ubuntu, don't use the distro-provided package - it is broken), unzip.
./configure
make
make install
gcc main.c -l:libffcall.a -o ma
main.c:
#include <callback.h>
// this is the closure function to be allocated
void function (void* data, va_alist alist)
{
int abc = va_arg_int(alist);
printf("data: %08p\n", data); // hex 0x14 = 20
printf("abc: %d\n", abc);
// va_start_type(alist[, return_type]);
// arg = va_arg_type(alist[, arg_type]);
// va_return_type(alist[[, return_type], return_value]);
// va_start_int(alist);
// int r = 666;
// va_return_int(alist, r);
}
int main(int argc, char* argv[])
{
int in1 = 10;
void * data = (void*) 20;
void(*incrementer1)(int abc) = (void(*)()) alloc_callback(&function, data);
// void(*incrementer1)() can have unlimited arguments, e.g. incrementer1(123,456);
// void(*incrementer1)(int abc) starts to throw errors...
incrementer1(123);
// free_callback(callback);
return EXIT_SUCCESS;
}
And if you use CMake, add the linker library after add_executable
add_library(libffcall STATIC IMPORTED)
set_target_properties(libffcall PROPERTIES
IMPORTED_LOCATION /usr/local/lib/libffcall.a)
target_link_libraries(BitmapLion libffcall)
or you could just dynamically link libffcall
target_link_libraries(BitmapLion ffcall)
Note:
You might want to include the libffcall headers and libraries, or create a cmake project with the contents of libffcall.
A simple solution "workaround" still is to create a class of virtual functions "interface" and inherit it in the caller class. Then pass it as a parameter "could be in the constructor" of the other class that you want to call your caller class back.
DEFINE Interface:
class CallBack
{
virtual callMeBack () {};
};
This is the class that you want to call you back:
class AnotherClass ()
{
public void RegisterMe(CallBack *callback)
{
m_callback = callback;
}
public void DoSomething ()
{
// DO STUFF
// .....
// then call
if (m_callback) m_callback->callMeBack();
}
private CallBack *m_callback = NULL;
};
And this is the class that will be called back.
class Caller : public CallBack
{
void DoSomthing ()
{
}
void callMeBack()
{
std::cout << "I got your message" << std::endl;
}
};
It is still difficult to connect C style callback functions with C++ class instances. I want to kind of rephrase the original question:
Some library you are using requires a C style function to be called back from that library. Changing the library API is out of the question since it is not your API.
You want the callback to be handled in your own C++ code in member methods
As you did not mention (exactly) what callback you want to handle I will give an example using GLFW callbacks for key input. (On a side note: I know GLFW offers some other mechanism to attach user data to their API, but that is not the topic here.)
I don't know any solution to this problem that doesn't include usage of some kind of static object. Let's look at our options:
Simple approach: Use C style global objects
As we always think in classes and instances we sometimes forget that in C++ we still have the whole arsenal of C at our hands. So sometimes this very simple solution does not come to mind.
Let's assume we have a class Presentation that should handle keyboard input. This could look like this:
struct KeyInput {
int pressedKey;
} KeyInputGlobal;
void globalKeyHandler(GLFWwindow* window, int key, int scancode, int action, int mods) {
KeyInputGlobal.pressedKey = key;
}
int Presentation::getCurrentKey()
{
return KeyInputGlobal.pressedKey;
}
void Presentation::initGLFW()
{
glfwInit();
glfwSetKeyCallback(window, globalKeyHandler);
}
We have a global Object KeyInputGlobal that should receive the key pressed. The function globalKeyHandler has exactly the C style API signature needed by the GLFW library to be able to call our code. It is activated on our member method initGLFW. If anywhere in our code we are interested in the currently pressed key we can just call the other member method Presentation::getCurrentKey
What is wrong with this approach?
Maybe it is all fine. Depends entirely on your use case. Maybe you are totally fine to just read the last pressed key somwhere in your application code. You don't care to have missed key pressed events. The simple approach is all you need.
To generalize: If you are able to fully process the callback in C style code, calculate some result and store it in a global object to be read later from other parts of your code, then it may indeed make sense to use this simple approach. On the plus side: It is very simple to understand. The downside? It feels a little bit like cheating, because you didn't really process the callback in your C++ code, you just used the results. If you think of the callback as an event and want each event to be properly processed in your member methods this approch won't be enough.
Another simple approach: Use C++ static objects
I guess many of us have already done this. Certainly I have. Thinking: Wait, we have a C++ concept of globals, that is using static. But we can keep the discussion short here: It may be more C++ style than using the C style from previous example, but the problems are the same - we still have globals, that are hard to bring together with non-static, regular member methods. For completeness, it would look like this in our class declaration:
class Presentation
{
public:
struct KeyInput {
int pressedKey;
};
static KeyInput KeyInputGlobal;
static void globalKeyHandler(GLFWwindow* window, int key, int scancode, int action, int mods) {
KeyInputGlobal.pressedKey = key;
}
int getCurrentKey()
{
return KeyInputGlobal.pressedKey;
}
...
}
Activating our callback would look the same, but we also have to define the static struct that receives the key pressed in our implementation:
void Presentation::initGLFW()
{
glfwInit();
glfwSetKeyCallback(window, globalKeyHandler);
}
//static
Presentation::KeyInput Presentation::KeyInputGlobal;
You might be inclined to just remove the static keyword from our callback method globalKeyHandler: The compiler will immediately tell you that you can no longer pass this to GLFW in glfwSetKeyCallback(). Now, if we only could connect static methods with regular methods somehow...
C++11 Event driven approach with statics and lambdas
The best solution I could find out is the following. It works and is somewhat elegant, but I still do not consider it perfect. Let's look at it and discuss:
void Presentation::initGLFW()
{
glfwInit();
static auto callback_static = [this](
GLFWwindow* window, int key, int scancode, int action, int mods) {
// because we have a this pointer we are now able to call a non-static member method:
key_callbackMember(window, key, scancode, action, mods);
};
glfwSetKeyCallback(window,
[](GLFWwindow* window, int key, int scancode, int action, int mods)
{
// only static methods can be called here as we cannot change glfw function parameter list to include instance pointer
callback_static(window, key, scancode, action, mods);
}
);
}
void Presentation::key_callbackMember(GLFWwindow* window, int key, int scancode, int action, int mods)
{
// we can now call anywhere in our code to process the key input:
app->handleInput(key, action);
}
The definition of callback_static is where we connect a static object with instance data, in this case this is an instance of our Presentation class. You can read the definition as follows: If callback_static is called anytime after this definition, all parameters will be passed to the member method key_callbackMember called at the Presentation instance just used. This definition has nothing to do with the GLFW library yet - it is just the preparation for the next step.
We now use a second lambda to register our callback with the library in glfwSetKeyCallback(). Again, if callback_static would not have been defined as static we could not pass it to GLFW here.
This is what happens at runtime after all the initializations, when GLFW calls our code:
GLFW recognizes a key event and calls our static object callback_static
callback_static has access to an instance of Presentation class and calls it's instance method key_callbackMember
Now that we are in 'object world' we can process the key event somewhere else. In this case we call the method handleInput on some arbitrary object app, that has been setup somewhere else in our code.
The good: We have achieved what we wanted with no need to define global objects outside our initialization method initGLFW. No need for C style globals.
The bad: Don't be fooled just because everything is neatly packed into one method. We still have static objects. And with them all the problems global objects have. E.g. multiple calls to our initialization method (with different instances of Presentation) would probably not have the effect you intended.
Summary
It is possible to connect C style callbacks of existing libraries to instances of classes in your own code. You can try to minimize houeskeeping code by defining the necessary objects in member methods of your code. But you still need one static object for each callback. If you want to connect several instances of your C++ code with a C style callback be prepared to introduce a more complicated management of your static objects than in the example above.
Hope this helps someone. Happy coding.
I can see that the init has the following override:
Init(CALLBACK_FUNC_EX callback_func, void * callback_parm)
where CALLBACK_FUNC_EX is
typedef void (*CALLBACK_FUNC_EX)(int, void *);
The type of pointer to non-static member function is different from pointer to ordinary function.
Type is void(*)(int) if it’s an ordinary or static member function.
Type is void(CLoggersInfra::*)(int) if it’s a non-static member function.
So you cannot pass a pointer to a non-static member function if it is expecting an ordinary function pointer.
Furthermore, a non-static member function has an implicit/hidden parameter to the object. The this pointer is implicitly passed as an argument to the member function call. So the member functions can be invoked only by providing an object.
If the API Init cannot be changed, a wrapper function (ordinary function or a class static member function) that invokes the member can be used. In the worst case, the object would be a global for the wrapper function to access.
CLoggersInfra* pLoggerInfra;
RedundencyManagerCallBackWrapper(int val)
{
pLoggerInfra->RedundencyManagerCallBack(val);
}
m_cRedundencyManager->Init(RedundencyManagerCallBackWrapper);
If the API Init can be changed, there are many alternatives - Object non-static member function pointer, Function Object, std::function or Interface Function.
See the post on callbacks for the different variations with C++ working examples.
This question and answer from the C++ FAQ Lite covers your question and the considerations involved in the answer quite nicely I think. Short snippet from the web page I linked:
Don’t.
Because a member function is meaningless without an object to invoke
it on, you can’t do this directly (if The X Window System was
rewritten in C++, it would probably pass references to objects around,
not just pointers to functions; naturally the objects would embody the
required function and probably a whole lot more).
Looks like std::mem_fn (C++11) does exactly what you need:
Function template std::mem_fn generates wrapper objects for pointers to members, which can store, copy, and invoke a pointer to member. Both references and pointers (including smart pointers) to an object can be used when invoking a std::mem_fn.

Invalid use of non-static member function when using cpp class [duplicate]

I'm using an API that requires me to pass a function pointer as a callback. I'm trying to use this API from my class but I'm getting compilation errors.
Here is what I did from my constructor:
m_cRedundencyManager->Init(this->RedundencyManagerCallBack);
This doesn't compile - I get the following error:
Error 8 error C3867: 'CLoggersInfra::RedundencyManagerCallBack': function call missing argument list; use '&CLoggersInfra::RedundencyManagerCallBack' to create a pointer to member
I tried the suggestion to use &CLoggersInfra::RedundencyManagerCallBack - didn't work for me.
Any suggestions/explanation for this??
I'm using VS2008.
Thanks!!
This is a simple question but the answer is surprisingly complex. The short answer is you can do what you're trying to do with std::bind1st or boost::bind. The longer answer is below.
The compiler is correct to suggest you use &CLoggersInfra::RedundencyManagerCallBack. First, if RedundencyManagerCallBack is a member function, the function itself doesn't belong to any particular instance of the class CLoggersInfra. It belongs to the class itself. If you've ever called a static class function before, you may have noticed you use the same SomeClass::SomeMemberFunction syntax. Since the function itself is 'static' in the sense that it belongs to the class rather than a particular instance, you use the same syntax. The '&' is necessary because technically speaking you don't pass functions directly -- functions are not real objects in C++. Instead you're technically passing the memory address for the function, that is, a pointer to where the function's instructions begin in memory. The consequence is the same though, you're effectively 'passing a function' as a parameter.
But that's only half the problem in this instance. As I said, RedundencyManagerCallBack the function doesn't 'belong' to any particular instance. But it sounds like you want to pass it as a callback with a particular instance in mind. To understand how to do this you need to understand what member functions really are: regular not-defined-in-any-class functions with an extra hidden parameter.
For example:
class A {
public:
A() : data(0) {}
void foo(int addToData) { this->data += addToData; }
int data;
};
...
A an_a_object;
an_a_object.foo(5);
A::foo(&an_a_object, 5); // This is the same as the line above!
std::cout << an_a_object.data; // Prints 10!
How many parameters does A::foo take? Normally we would say 1. But under the hood, foo really takes 2. Looking at A::foo's definition, it needs a specific instance of A in order for the 'this' pointer to be meaningful (the compiler needs to know what 'this' is). The way you usually specify what you want 'this' to be is through the syntax MyObject.MyMemberFunction(). But this is just syntactic sugar for passing the address of MyObject as the first parameter to MyMemberFunction. Similarly, when we declare member functions inside class definitions we don't put 'this' in the parameter list, but this is just a gift from the language designers to save typing. Instead you have to specify that a member function is static to opt out of it automatically getting the extra 'this' parameter. If the C++ compiler translated the above example to C code (the original C++ compiler actually worked that way), it would probably write something like this:
struct A {
int data;
};
void a_init(A* to_init)
{
to_init->data = 0;
}
void a_foo(A* this, int addToData)
{
this->data += addToData;
}
...
A an_a_object;
a_init(0); // Before constructor call was implicit
a_foo(&an_a_object, 5); // Used to be an_a_object.foo(5);
Returning to your example, there is now an obvious problem. 'Init' wants a pointer to a function that takes one parameter. But &CLoggersInfra::RedundencyManagerCallBack is a pointer to a function that takes two parameters, it's normal parameter and the secret 'this' parameter. That's why you're still getting a compiler error (as a side note: If you've ever used Python, this kind of confusion is why a 'self' parameter is required for all member functions).
The verbose way to handle this is to create a special object that holds a pointer to the instance you want and has a member function called something like 'run' or 'execute' (or overloads the '()' operator) that takes the parameters for the member function, and simply calls the member function with those parameters on the stored instance. But this would require you to change 'Init' to take your special object rather than a raw function pointer, and it sounds like Init is someone else's code. And making a special class for every time this problem comes up will lead to code bloat.
So now, finally, the good solution, boost::bind and boost::function, the documentation for each you can find here:
boost::bind docs,
boost::function docs
boost::bind will let you take a function, and a parameter to that function, and make a new function where that parameter is 'locked' in place. So if I have a function that adds two integers, I can use boost::bind to make a new function where one of the parameters is locked to say 5. This new function will only take one integer parameter, and will always add 5 specifically to it. Using this technique, you can 'lock in' the hidden 'this' parameter to be a particular class instance, and generate a new function that only takes one parameter, just like you want (note that the hidden parameter is always the first parameter, and the normal parameters come in order after it). Look at the boost::bind docs for examples, they even specifically discuss using it for member functions. Technically there is a standard function called [std::bind1st][3] that you could use as well, but boost::bind is more general.
Of course, there's just one more catch. boost::bind will make a nice boost::function for you, but this is still technically not a raw function pointer like Init probably wants. Thankfully, boost provides a way to convert boost::function's to raw pointers, as documented on StackOverflow here. How it implements this is beyond the scope of this answer, though it's interesting too.
Don't worry if this seems ludicrously hard -- your question intersects several of C++'s darker corners, and boost::bind is incredibly useful once you learn it.
C++11 update: Instead of boost::bind you can now use a lambda function that captures 'this'. This is basically having the compiler generate the same thing for you.
That doesn't work because a member function pointer cannot be handled like a normal function pointer, because it expects a "this" object argument.
Instead you can pass a static member function as follows, which are like normal non-member functions in this regard:
m_cRedundencyManager->Init(&CLoggersInfra::Callback, this);
The function can be defined as follows
static void Callback(int other_arg, void * this_pointer) {
CLoggersInfra * self = static_cast<CLoggersInfra*>(this_pointer);
self->RedundencyManagerCallBack(other_arg);
}
This answer is a reply to a comment above and does not work with VisualStudio 2008 but should be preferred with more recent compilers.
Meanwhile you don't have to use a void pointer anymore and there is also no need for boost since std::bind and std::function are available. One advantage (in comparison to void pointers) is type safety since the return type and the arguments are explicitly stated using std::function:
// std::function<return_type(list of argument_type(s))>
void Init(std::function<void(void)> f);
Then you can create the function pointer with std::bind and pass it to Init:
auto cLoggersInfraInstance = CLoggersInfra();
auto callback = std::bind(&CLoggersInfra::RedundencyManagerCallBack, cLoggersInfraInstance);
Init(callback);
Complete example for using std::bind with member, static members and non member functions:
#include <functional>
#include <iostream>
#include <string>
class RedundencyManager // incl. Typo ;-)
{
public:
// std::function<return_type(list of argument_type(s))>
std::string Init(std::function<std::string(void)> f)
{
return f();
}
};
class CLoggersInfra
{
private:
std::string member = "Hello from non static member callback!";
public:
static std::string RedundencyManagerCallBack()
{
return "Hello from static member callback!";
}
std::string NonStaticRedundencyManagerCallBack()
{
return member;
}
};
std::string NonMemberCallBack()
{
return "Hello from non member function!";
}
int main()
{
auto instance = RedundencyManager();
auto callback1 = std::bind(&NonMemberCallBack);
std::cout << instance.Init(callback1) << "\n";
// Similar to non member function.
auto callback2 = std::bind(&CLoggersInfra::RedundencyManagerCallBack);
std::cout << instance.Init(callback2) << "\n";
// Class instance is passed to std::bind as second argument.
// (heed that I call the constructor of CLoggersInfra)
auto callback3 = std::bind(&CLoggersInfra::NonStaticRedundencyManagerCallBack,
CLoggersInfra());
std::cout << instance.Init(callback3) << "\n";
}
Possible output:
Hello from non member function!
Hello from static member callback!
Hello from non static member callback!
Furthermore using std::placeholders you can dynamically pass arguments to the callback (e.g. this enables the usage of return f("MyString"); in Init if f has a string parameter).
What argument does Init take? What is the new error message?
Method pointers in C++ are a bit difficult to use. Besides the method pointer itself, you also need to provide an instance pointer (in your case this). Maybe Init expects it as a separate argument?
A pointer to a class member function is not the same as a pointer to a function. A class member takes an implicit extra argument (the this pointer), and uses a different calling convention.
If your API expects a nonmember callback function, that's what you have to pass to it.
Is m_cRedundencyManager able to use member functions? Most callbacks are set up to use regular functions or static member functions. Take a look at this page at C++ FAQ Lite for more information.
Update: The function declaration you provided shows that m_cRedundencyManager is expecting a function of the form: void yourCallbackFunction(int, void *). Member functions are therefore unacceptable as callbacks in this case. A static member function may work, but if that is unacceptable in your case, the following code would also work. Note that it uses an evil cast from void *.
// in your CLoggersInfra constructor:
m_cRedundencyManager->Init(myRedundencyManagerCallBackHandler, this);
// in your CLoggersInfra header:
void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr);
// in your CLoggersInfra source file:
void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr)
{
((CLoggersInfra *)CLoggersInfraPtr)->RedundencyManagerCallBack(i);
}
Necromancing.
I think the answers to date are a little unclear.
Let's make an example:
Supposed you have an array of pixels (array of ARGB int8_t values)
// A RGB image
int8_t* pixels = new int8_t[1024*768*4];
Now you want to generate a PNG.
To do so, you call the function toJpeg
bool ok = toJpeg(writeByte, pixels, width, height);
where writeByte is a callback-function
void writeByte(unsigned char oneByte)
{
fputc(oneByte, output);
}
The problem here: FILE* output has to be a global variable.
Very bad if you're in a multithreaded environment (e.g. a http-server).
So you need some way to make output a non-global variable, while retaining the callback signature.
The immediate solution that springs into mind is a closure, which we can emulate using a class with a member function.
class BadIdea {
private:
FILE* m_stream;
public:
BadIdea(FILE* stream) {
this->m_stream = stream;
}
void writeByte(unsigned char oneByte){
fputc(oneByte, this->m_stream);
}
};
And then do
FILE *fp = fopen(filename, "wb");
BadIdea* foobar = new BadIdea(fp);
bool ok = TooJpeg::writeJpeg(foobar->writeByte, image, width, height);
delete foobar;
fflush(fp);
fclose(fp);
However, contrary to expectations, this does not work.
The reason is, C++ member functions are kinda implemented like C# extension functions.
So you have
class/struct BadIdea
{
FILE* m_stream;
}
and
static class BadIdeaExtensions
{
public static writeByte(this BadIdea instance, unsigned char oneByte)
{
fputc(oneByte, instance->m_stream);
}
}
So when you want to call writeByte, you need pass not only the address of writeByte, but also the address of the BadIdea-instance.
So when you have a typedef for the writeByte procedure, and it looks like this
typedef void (*WRITE_ONE_BYTE)(unsigned char);
And you have a writeJpeg signature that looks like this
bool writeJpeg(WRITE_ONE_BYTE output, uint8_t* pixels, uint32_t
width, uint32_t height))
{ ... }
it's fundamentally impossible to pass a two-address member function to a one-address function pointer (without modifying writeJpeg), and there's no way around it.
The next best thing that you can do in C++, is using a lambda-function:
FILE *fp = fopen(filename, "wb");
auto lambda = [fp](unsigned char oneByte) { fputc(oneByte, fp); };
bool ok = TooJpeg::writeJpeg(lambda, image, width, height);
However, because lambda is doing nothing different, than passing an instance to a hidden class (such as the "BadIdea"-class), you need to modify the signature of writeJpeg.
The advantage of lambda over a manual class, is that you just need to change one typedef
typedef void (*WRITE_ONE_BYTE)(unsigned char);
to
using WRITE_ONE_BYTE = std::function<void(unsigned char)>;
And then you can leave everything else untouched.
You could also use std::bind
auto f = std::bind(&BadIdea::writeByte, &foobar);
But this, behind the scene, just creates a lambda function, which then also needs the change in typedef.
So no, there is no way to pass a member function to a method that requires a static function-pointer.
But lambdas are the easy way around, provided that you have control over the source.
Otherwise, you're out of luck.
There's nothing you can do with C++.
Note:
std::function requires #include <functional>
However, since C++ allows you to use C as well, you can do this with libffcall in plain C, if you don't mind linking a dependency.
Download libffcall from GNU (at least on ubuntu, don't use the distro-provided package - it is broken), unzip.
./configure
make
make install
gcc main.c -l:libffcall.a -o ma
main.c:
#include <callback.h>
// this is the closure function to be allocated
void function (void* data, va_alist alist)
{
int abc = va_arg_int(alist);
printf("data: %08p\n", data); // hex 0x14 = 20
printf("abc: %d\n", abc);
// va_start_type(alist[, return_type]);
// arg = va_arg_type(alist[, arg_type]);
// va_return_type(alist[[, return_type], return_value]);
// va_start_int(alist);
// int r = 666;
// va_return_int(alist, r);
}
int main(int argc, char* argv[])
{
int in1 = 10;
void * data = (void*) 20;
void(*incrementer1)(int abc) = (void(*)()) alloc_callback(&function, data);
// void(*incrementer1)() can have unlimited arguments, e.g. incrementer1(123,456);
// void(*incrementer1)(int abc) starts to throw errors...
incrementer1(123);
// free_callback(callback);
return EXIT_SUCCESS;
}
And if you use CMake, add the linker library after add_executable
add_library(libffcall STATIC IMPORTED)
set_target_properties(libffcall PROPERTIES
IMPORTED_LOCATION /usr/local/lib/libffcall.a)
target_link_libraries(BitmapLion libffcall)
or you could just dynamically link libffcall
target_link_libraries(BitmapLion ffcall)
Note:
You might want to include the libffcall headers and libraries, or create a cmake project with the contents of libffcall.
A simple solution "workaround" still is to create a class of virtual functions "interface" and inherit it in the caller class. Then pass it as a parameter "could be in the constructor" of the other class that you want to call your caller class back.
DEFINE Interface:
class CallBack
{
virtual callMeBack () {};
};
This is the class that you want to call you back:
class AnotherClass ()
{
public void RegisterMe(CallBack *callback)
{
m_callback = callback;
}
public void DoSomething ()
{
// DO STUFF
// .....
// then call
if (m_callback) m_callback->callMeBack();
}
private CallBack *m_callback = NULL;
};
And this is the class that will be called back.
class Caller : public CallBack
{
void DoSomthing ()
{
}
void callMeBack()
{
std::cout << "I got your message" << std::endl;
}
};
It is still difficult to connect C style callback functions with C++ class instances. I want to kind of rephrase the original question:
Some library you are using requires a C style function to be called back from that library. Changing the library API is out of the question since it is not your API.
You want the callback to be handled in your own C++ code in member methods
As you did not mention (exactly) what callback you want to handle I will give an example using GLFW callbacks for key input. (On a side note: I know GLFW offers some other mechanism to attach user data to their API, but that is not the topic here.)
I don't know any solution to this problem that doesn't include usage of some kind of static object. Let's look at our options:
Simple approach: Use C style global objects
As we always think in classes and instances we sometimes forget that in C++ we still have the whole arsenal of C at our hands. So sometimes this very simple solution does not come to mind.
Let's assume we have a class Presentation that should handle keyboard input. This could look like this:
struct KeyInput {
int pressedKey;
} KeyInputGlobal;
void globalKeyHandler(GLFWwindow* window, int key, int scancode, int action, int mods) {
KeyInputGlobal.pressedKey = key;
}
int Presentation::getCurrentKey()
{
return KeyInputGlobal.pressedKey;
}
void Presentation::initGLFW()
{
glfwInit();
glfwSetKeyCallback(window, globalKeyHandler);
}
We have a global Object KeyInputGlobal that should receive the key pressed. The function globalKeyHandler has exactly the C style API signature needed by the GLFW library to be able to call our code. It is activated on our member method initGLFW. If anywhere in our code we are interested in the currently pressed key we can just call the other member method Presentation::getCurrentKey
What is wrong with this approach?
Maybe it is all fine. Depends entirely on your use case. Maybe you are totally fine to just read the last pressed key somwhere in your application code. You don't care to have missed key pressed events. The simple approach is all you need.
To generalize: If you are able to fully process the callback in C style code, calculate some result and store it in a global object to be read later from other parts of your code, then it may indeed make sense to use this simple approach. On the plus side: It is very simple to understand. The downside? It feels a little bit like cheating, because you didn't really process the callback in your C++ code, you just used the results. If you think of the callback as an event and want each event to be properly processed in your member methods this approch won't be enough.
Another simple approach: Use C++ static objects
I guess many of us have already done this. Certainly I have. Thinking: Wait, we have a C++ concept of globals, that is using static. But we can keep the discussion short here: It may be more C++ style than using the C style from previous example, but the problems are the same - we still have globals, that are hard to bring together with non-static, regular member methods. For completeness, it would look like this in our class declaration:
class Presentation
{
public:
struct KeyInput {
int pressedKey;
};
static KeyInput KeyInputGlobal;
static void globalKeyHandler(GLFWwindow* window, int key, int scancode, int action, int mods) {
KeyInputGlobal.pressedKey = key;
}
int getCurrentKey()
{
return KeyInputGlobal.pressedKey;
}
...
}
Activating our callback would look the same, but we also have to define the static struct that receives the key pressed in our implementation:
void Presentation::initGLFW()
{
glfwInit();
glfwSetKeyCallback(window, globalKeyHandler);
}
//static
Presentation::KeyInput Presentation::KeyInputGlobal;
You might be inclined to just remove the static keyword from our callback method globalKeyHandler: The compiler will immediately tell you that you can no longer pass this to GLFW in glfwSetKeyCallback(). Now, if we only could connect static methods with regular methods somehow...
C++11 Event driven approach with statics and lambdas
The best solution I could find out is the following. It works and is somewhat elegant, but I still do not consider it perfect. Let's look at it and discuss:
void Presentation::initGLFW()
{
glfwInit();
static auto callback_static = [this](
GLFWwindow* window, int key, int scancode, int action, int mods) {
// because we have a this pointer we are now able to call a non-static member method:
key_callbackMember(window, key, scancode, action, mods);
};
glfwSetKeyCallback(window,
[](GLFWwindow* window, int key, int scancode, int action, int mods)
{
// only static methods can be called here as we cannot change glfw function parameter list to include instance pointer
callback_static(window, key, scancode, action, mods);
}
);
}
void Presentation::key_callbackMember(GLFWwindow* window, int key, int scancode, int action, int mods)
{
// we can now call anywhere in our code to process the key input:
app->handleInput(key, action);
}
The definition of callback_static is where we connect a static object with instance data, in this case this is an instance of our Presentation class. You can read the definition as follows: If callback_static is called anytime after this definition, all parameters will be passed to the member method key_callbackMember called at the Presentation instance just used. This definition has nothing to do with the GLFW library yet - it is just the preparation for the next step.
We now use a second lambda to register our callback with the library in glfwSetKeyCallback(). Again, if callback_static would not have been defined as static we could not pass it to GLFW here.
This is what happens at runtime after all the initializations, when GLFW calls our code:
GLFW recognizes a key event and calls our static object callback_static
callback_static has access to an instance of Presentation class and calls it's instance method key_callbackMember
Now that we are in 'object world' we can process the key event somewhere else. In this case we call the method handleInput on some arbitrary object app, that has been setup somewhere else in our code.
The good: We have achieved what we wanted with no need to define global objects outside our initialization method initGLFW. No need for C style globals.
The bad: Don't be fooled just because everything is neatly packed into one method. We still have static objects. And with them all the problems global objects have. E.g. multiple calls to our initialization method (with different instances of Presentation) would probably not have the effect you intended.
Summary
It is possible to connect C style callbacks of existing libraries to instances of classes in your own code. You can try to minimize houeskeeping code by defining the necessary objects in member methods of your code. But you still need one static object for each callback. If you want to connect several instances of your C++ code with a C style callback be prepared to introduce a more complicated management of your static objects than in the example above.
Hope this helps someone. Happy coding.
I can see that the init has the following override:
Init(CALLBACK_FUNC_EX callback_func, void * callback_parm)
where CALLBACK_FUNC_EX is
typedef void (*CALLBACK_FUNC_EX)(int, void *);
The type of pointer to non-static member function is different from pointer to ordinary function.
Type is void(*)(int) if it’s an ordinary or static member function.
Type is void(CLoggersInfra::*)(int) if it’s a non-static member function.
So you cannot pass a pointer to a non-static member function if it is expecting an ordinary function pointer.
Furthermore, a non-static member function has an implicit/hidden parameter to the object. The this pointer is implicitly passed as an argument to the member function call. So the member functions can be invoked only by providing an object.
If the API Init cannot be changed, a wrapper function (ordinary function or a class static member function) that invokes the member can be used. In the worst case, the object would be a global for the wrapper function to access.
CLoggersInfra* pLoggerInfra;
RedundencyManagerCallBackWrapper(int val)
{
pLoggerInfra->RedundencyManagerCallBack(val);
}
m_cRedundencyManager->Init(RedundencyManagerCallBackWrapper);
If the API Init can be changed, there are many alternatives - Object non-static member function pointer, Function Object, std::function or Interface Function.
See the post on callbacks for the different variations with C++ working examples.
This question and answer from the C++ FAQ Lite covers your question and the considerations involved in the answer quite nicely I think. Short snippet from the web page I linked:
Don’t.
Because a member function is meaningless without an object to invoke
it on, you can’t do this directly (if The X Window System was
rewritten in C++, it would probably pass references to objects around,
not just pointers to functions; naturally the objects would embody the
required function and probably a whole lot more).
There's surprisingly a simple way to do so in c++14 or above:
auto callback = [this](){ this->methodCB(); };
subscribeToEvent(callback);
**assuming subscribeToEvent gets std::function<void()>
Looks like std::mem_fn (C++11) does exactly what you need:
Function template std::mem_fn generates wrapper objects for pointers to members, which can store, copy, and invoke a pointer to member. Both references and pointers (including smart pointers) to an object can be used when invoking a std::mem_fn.

Pass a member function as argument [duplicate]

I'm using an API that requires me to pass a function pointer as a callback. I'm trying to use this API from my class but I'm getting compilation errors.
Here is what I did from my constructor:
m_cRedundencyManager->Init(this->RedundencyManagerCallBack);
This doesn't compile - I get the following error:
Error 8 error C3867: 'CLoggersInfra::RedundencyManagerCallBack': function call missing argument list; use '&CLoggersInfra::RedundencyManagerCallBack' to create a pointer to member
I tried the suggestion to use &CLoggersInfra::RedundencyManagerCallBack - didn't work for me.
Any suggestions/explanation for this??
I'm using VS2008.
Thanks!!
This is a simple question but the answer is surprisingly complex. The short answer is you can do what you're trying to do with std::bind1st or boost::bind. The longer answer is below.
The compiler is correct to suggest you use &CLoggersInfra::RedundencyManagerCallBack. First, if RedundencyManagerCallBack is a member function, the function itself doesn't belong to any particular instance of the class CLoggersInfra. It belongs to the class itself. If you've ever called a static class function before, you may have noticed you use the same SomeClass::SomeMemberFunction syntax. Since the function itself is 'static' in the sense that it belongs to the class rather than a particular instance, you use the same syntax. The '&' is necessary because technically speaking you don't pass functions directly -- functions are not real objects in C++. Instead you're technically passing the memory address for the function, that is, a pointer to where the function's instructions begin in memory. The consequence is the same though, you're effectively 'passing a function' as a parameter.
But that's only half the problem in this instance. As I said, RedundencyManagerCallBack the function doesn't 'belong' to any particular instance. But it sounds like you want to pass it as a callback with a particular instance in mind. To understand how to do this you need to understand what member functions really are: regular not-defined-in-any-class functions with an extra hidden parameter.
For example:
class A {
public:
A() : data(0) {}
void foo(int addToData) { this->data += addToData; }
int data;
};
...
A an_a_object;
an_a_object.foo(5);
A::foo(&an_a_object, 5); // This is the same as the line above!
std::cout << an_a_object.data; // Prints 10!
How many parameters does A::foo take? Normally we would say 1. But under the hood, foo really takes 2. Looking at A::foo's definition, it needs a specific instance of A in order for the 'this' pointer to be meaningful (the compiler needs to know what 'this' is). The way you usually specify what you want 'this' to be is through the syntax MyObject.MyMemberFunction(). But this is just syntactic sugar for passing the address of MyObject as the first parameter to MyMemberFunction. Similarly, when we declare member functions inside class definitions we don't put 'this' in the parameter list, but this is just a gift from the language designers to save typing. Instead you have to specify that a member function is static to opt out of it automatically getting the extra 'this' parameter. If the C++ compiler translated the above example to C code (the original C++ compiler actually worked that way), it would probably write something like this:
struct A {
int data;
};
void a_init(A* to_init)
{
to_init->data = 0;
}
void a_foo(A* this, int addToData)
{
this->data += addToData;
}
...
A an_a_object;
a_init(0); // Before constructor call was implicit
a_foo(&an_a_object, 5); // Used to be an_a_object.foo(5);
Returning to your example, there is now an obvious problem. 'Init' wants a pointer to a function that takes one parameter. But &CLoggersInfra::RedundencyManagerCallBack is a pointer to a function that takes two parameters, it's normal parameter and the secret 'this' parameter. That's why you're still getting a compiler error (as a side note: If you've ever used Python, this kind of confusion is why a 'self' parameter is required for all member functions).
The verbose way to handle this is to create a special object that holds a pointer to the instance you want and has a member function called something like 'run' or 'execute' (or overloads the '()' operator) that takes the parameters for the member function, and simply calls the member function with those parameters on the stored instance. But this would require you to change 'Init' to take your special object rather than a raw function pointer, and it sounds like Init is someone else's code. And making a special class for every time this problem comes up will lead to code bloat.
So now, finally, the good solution, boost::bind and boost::function, the documentation for each you can find here:
boost::bind docs,
boost::function docs
boost::bind will let you take a function, and a parameter to that function, and make a new function where that parameter is 'locked' in place. So if I have a function that adds two integers, I can use boost::bind to make a new function where one of the parameters is locked to say 5. This new function will only take one integer parameter, and will always add 5 specifically to it. Using this technique, you can 'lock in' the hidden 'this' parameter to be a particular class instance, and generate a new function that only takes one parameter, just like you want (note that the hidden parameter is always the first parameter, and the normal parameters come in order after it). Look at the boost::bind docs for examples, they even specifically discuss using it for member functions. Technically there is a standard function called [std::bind1st][3] that you could use as well, but boost::bind is more general.
Of course, there's just one more catch. boost::bind will make a nice boost::function for you, but this is still technically not a raw function pointer like Init probably wants. Thankfully, boost provides a way to convert boost::function's to raw pointers, as documented on StackOverflow here. How it implements this is beyond the scope of this answer, though it's interesting too.
Don't worry if this seems ludicrously hard -- your question intersects several of C++'s darker corners, and boost::bind is incredibly useful once you learn it.
C++11 update: Instead of boost::bind you can now use a lambda function that captures 'this'. This is basically having the compiler generate the same thing for you.
That doesn't work because a member function pointer cannot be handled like a normal function pointer, because it expects a "this" object argument.
Instead you can pass a static member function as follows, which are like normal non-member functions in this regard:
m_cRedundencyManager->Init(&CLoggersInfra::Callback, this);
The function can be defined as follows
static void Callback(int other_arg, void * this_pointer) {
CLoggersInfra * self = static_cast<CLoggersInfra*>(this_pointer);
self->RedundencyManagerCallBack(other_arg);
}
This answer is a reply to a comment above and does not work with VisualStudio 2008 but should be preferred with more recent compilers.
Meanwhile you don't have to use a void pointer anymore and there is also no need for boost since std::bind and std::function are available. One advantage (in comparison to void pointers) is type safety since the return type and the arguments are explicitly stated using std::function:
// std::function<return_type(list of argument_type(s))>
void Init(std::function<void(void)> f);
Then you can create the function pointer with std::bind and pass it to Init:
auto cLoggersInfraInstance = CLoggersInfra();
auto callback = std::bind(&CLoggersInfra::RedundencyManagerCallBack, cLoggersInfraInstance);
Init(callback);
Complete example for using std::bind with member, static members and non member functions:
#include <functional>
#include <iostream>
#include <string>
class RedundencyManager // incl. Typo ;-)
{
public:
// std::function<return_type(list of argument_type(s))>
std::string Init(std::function<std::string(void)> f)
{
return f();
}
};
class CLoggersInfra
{
private:
std::string member = "Hello from non static member callback!";
public:
static std::string RedundencyManagerCallBack()
{
return "Hello from static member callback!";
}
std::string NonStaticRedundencyManagerCallBack()
{
return member;
}
};
std::string NonMemberCallBack()
{
return "Hello from non member function!";
}
int main()
{
auto instance = RedundencyManager();
auto callback1 = std::bind(&NonMemberCallBack);
std::cout << instance.Init(callback1) << "\n";
// Similar to non member function.
auto callback2 = std::bind(&CLoggersInfra::RedundencyManagerCallBack);
std::cout << instance.Init(callback2) << "\n";
// Class instance is passed to std::bind as second argument.
// (heed that I call the constructor of CLoggersInfra)
auto callback3 = std::bind(&CLoggersInfra::NonStaticRedundencyManagerCallBack,
CLoggersInfra());
std::cout << instance.Init(callback3) << "\n";
}
Possible output:
Hello from non member function!
Hello from static member callback!
Hello from non static member callback!
Furthermore using std::placeholders you can dynamically pass arguments to the callback (e.g. this enables the usage of return f("MyString"); in Init if f has a string parameter).
What argument does Init take? What is the new error message?
Method pointers in C++ are a bit difficult to use. Besides the method pointer itself, you also need to provide an instance pointer (in your case this). Maybe Init expects it as a separate argument?
A pointer to a class member function is not the same as a pointer to a function. A class member takes an implicit extra argument (the this pointer), and uses a different calling convention.
If your API expects a nonmember callback function, that's what you have to pass to it.
Is m_cRedundencyManager able to use member functions? Most callbacks are set up to use regular functions or static member functions. Take a look at this page at C++ FAQ Lite for more information.
Update: The function declaration you provided shows that m_cRedundencyManager is expecting a function of the form: void yourCallbackFunction(int, void *). Member functions are therefore unacceptable as callbacks in this case. A static member function may work, but if that is unacceptable in your case, the following code would also work. Note that it uses an evil cast from void *.
// in your CLoggersInfra constructor:
m_cRedundencyManager->Init(myRedundencyManagerCallBackHandler, this);
// in your CLoggersInfra header:
void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr);
// in your CLoggersInfra source file:
void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr)
{
((CLoggersInfra *)CLoggersInfraPtr)->RedundencyManagerCallBack(i);
}
Necromancing.
I think the answers to date are a little unclear.
Let's make an example:
Supposed you have an array of pixels (array of ARGB int8_t values)
// A RGB image
int8_t* pixels = new int8_t[1024*768*4];
Now you want to generate a PNG.
To do so, you call the function toJpeg
bool ok = toJpeg(writeByte, pixels, width, height);
where writeByte is a callback-function
void writeByte(unsigned char oneByte)
{
fputc(oneByte, output);
}
The problem here: FILE* output has to be a global variable.
Very bad if you're in a multithreaded environment (e.g. a http-server).
So you need some way to make output a non-global variable, while retaining the callback signature.
The immediate solution that springs into mind is a closure, which we can emulate using a class with a member function.
class BadIdea {
private:
FILE* m_stream;
public:
BadIdea(FILE* stream) {
this->m_stream = stream;
}
void writeByte(unsigned char oneByte){
fputc(oneByte, this->m_stream);
}
};
And then do
FILE *fp = fopen(filename, "wb");
BadIdea* foobar = new BadIdea(fp);
bool ok = TooJpeg::writeJpeg(foobar->writeByte, image, width, height);
delete foobar;
fflush(fp);
fclose(fp);
However, contrary to expectations, this does not work.
The reason is, C++ member functions are kinda implemented like C# extension functions.
So you have
class/struct BadIdea
{
FILE* m_stream;
}
and
static class BadIdeaExtensions
{
public static writeByte(this BadIdea instance, unsigned char oneByte)
{
fputc(oneByte, instance->m_stream);
}
}
So when you want to call writeByte, you need pass not only the address of writeByte, but also the address of the BadIdea-instance.
So when you have a typedef for the writeByte procedure, and it looks like this
typedef void (*WRITE_ONE_BYTE)(unsigned char);
And you have a writeJpeg signature that looks like this
bool writeJpeg(WRITE_ONE_BYTE output, uint8_t* pixels, uint32_t
width, uint32_t height))
{ ... }
it's fundamentally impossible to pass a two-address member function to a one-address function pointer (without modifying writeJpeg), and there's no way around it.
The next best thing that you can do in C++, is using a lambda-function:
FILE *fp = fopen(filename, "wb");
auto lambda = [fp](unsigned char oneByte) { fputc(oneByte, fp); };
bool ok = TooJpeg::writeJpeg(lambda, image, width, height);
However, because lambda is doing nothing different, than passing an instance to a hidden class (such as the "BadIdea"-class), you need to modify the signature of writeJpeg.
The advantage of lambda over a manual class, is that you just need to change one typedef
typedef void (*WRITE_ONE_BYTE)(unsigned char);
to
using WRITE_ONE_BYTE = std::function<void(unsigned char)>;
And then you can leave everything else untouched.
You could also use std::bind
auto f = std::bind(&BadIdea::writeByte, &foobar);
But this, behind the scene, just creates a lambda function, which then also needs the change in typedef.
So no, there is no way to pass a member function to a method that requires a static function-pointer.
But lambdas are the easy way around, provided that you have control over the source.
Otherwise, you're out of luck.
There's nothing you can do with C++.
Note:
std::function requires #include <functional>
However, since C++ allows you to use C as well, you can do this with libffcall in plain C, if you don't mind linking a dependency.
Download libffcall from GNU (at least on ubuntu, don't use the distro-provided package - it is broken), unzip.
./configure
make
make install
gcc main.c -l:libffcall.a -o ma
main.c:
#include <callback.h>
// this is the closure function to be allocated
void function (void* data, va_alist alist)
{
int abc = va_arg_int(alist);
printf("data: %08p\n", data); // hex 0x14 = 20
printf("abc: %d\n", abc);
// va_start_type(alist[, return_type]);
// arg = va_arg_type(alist[, arg_type]);
// va_return_type(alist[[, return_type], return_value]);
// va_start_int(alist);
// int r = 666;
// va_return_int(alist, r);
}
int main(int argc, char* argv[])
{
int in1 = 10;
void * data = (void*) 20;
void(*incrementer1)(int abc) = (void(*)()) alloc_callback(&function, data);
// void(*incrementer1)() can have unlimited arguments, e.g. incrementer1(123,456);
// void(*incrementer1)(int abc) starts to throw errors...
incrementer1(123);
// free_callback(callback);
return EXIT_SUCCESS;
}
And if you use CMake, add the linker library after add_executable
add_library(libffcall STATIC IMPORTED)
set_target_properties(libffcall PROPERTIES
IMPORTED_LOCATION /usr/local/lib/libffcall.a)
target_link_libraries(BitmapLion libffcall)
or you could just dynamically link libffcall
target_link_libraries(BitmapLion ffcall)
Note:
You might want to include the libffcall headers and libraries, or create a cmake project with the contents of libffcall.
A simple solution "workaround" still is to create a class of virtual functions "interface" and inherit it in the caller class. Then pass it as a parameter "could be in the constructor" of the other class that you want to call your caller class back.
DEFINE Interface:
class CallBack
{
virtual callMeBack () {};
};
This is the class that you want to call you back:
class AnotherClass ()
{
public void RegisterMe(CallBack *callback)
{
m_callback = callback;
}
public void DoSomething ()
{
// DO STUFF
// .....
// then call
if (m_callback) m_callback->callMeBack();
}
private CallBack *m_callback = NULL;
};
And this is the class that will be called back.
class Caller : public CallBack
{
void DoSomthing ()
{
}
void callMeBack()
{
std::cout << "I got your message" << std::endl;
}
};
It is still difficult to connect C style callback functions with C++ class instances. I want to kind of rephrase the original question:
Some library you are using requires a C style function to be called back from that library. Changing the library API is out of the question since it is not your API.
You want the callback to be handled in your own C++ code in member methods
As you did not mention (exactly) what callback you want to handle I will give an example using GLFW callbacks for key input. (On a side note: I know GLFW offers some other mechanism to attach user data to their API, but that is not the topic here.)
I don't know any solution to this problem that doesn't include usage of some kind of static object. Let's look at our options:
Simple approach: Use C style global objects
As we always think in classes and instances we sometimes forget that in C++ we still have the whole arsenal of C at our hands. So sometimes this very simple solution does not come to mind.
Let's assume we have a class Presentation that should handle keyboard input. This could look like this:
struct KeyInput {
int pressedKey;
} KeyInputGlobal;
void globalKeyHandler(GLFWwindow* window, int key, int scancode, int action, int mods) {
KeyInputGlobal.pressedKey = key;
}
int Presentation::getCurrentKey()
{
return KeyInputGlobal.pressedKey;
}
void Presentation::initGLFW()
{
glfwInit();
glfwSetKeyCallback(window, globalKeyHandler);
}
We have a global Object KeyInputGlobal that should receive the key pressed. The function globalKeyHandler has exactly the C style API signature needed by the GLFW library to be able to call our code. It is activated on our member method initGLFW. If anywhere in our code we are interested in the currently pressed key we can just call the other member method Presentation::getCurrentKey
What is wrong with this approach?
Maybe it is all fine. Depends entirely on your use case. Maybe you are totally fine to just read the last pressed key somwhere in your application code. You don't care to have missed key pressed events. The simple approach is all you need.
To generalize: If you are able to fully process the callback in C style code, calculate some result and store it in a global object to be read later from other parts of your code, then it may indeed make sense to use this simple approach. On the plus side: It is very simple to understand. The downside? It feels a little bit like cheating, because you didn't really process the callback in your C++ code, you just used the results. If you think of the callback as an event and want each event to be properly processed in your member methods this approch won't be enough.
Another simple approach: Use C++ static objects
I guess many of us have already done this. Certainly I have. Thinking: Wait, we have a C++ concept of globals, that is using static. But we can keep the discussion short here: It may be more C++ style than using the C style from previous example, but the problems are the same - we still have globals, that are hard to bring together with non-static, regular member methods. For completeness, it would look like this in our class declaration:
class Presentation
{
public:
struct KeyInput {
int pressedKey;
};
static KeyInput KeyInputGlobal;
static void globalKeyHandler(GLFWwindow* window, int key, int scancode, int action, int mods) {
KeyInputGlobal.pressedKey = key;
}
int getCurrentKey()
{
return KeyInputGlobal.pressedKey;
}
...
}
Activating our callback would look the same, but we also have to define the static struct that receives the key pressed in our implementation:
void Presentation::initGLFW()
{
glfwInit();
glfwSetKeyCallback(window, globalKeyHandler);
}
//static
Presentation::KeyInput Presentation::KeyInputGlobal;
You might be inclined to just remove the static keyword from our callback method globalKeyHandler: The compiler will immediately tell you that you can no longer pass this to GLFW in glfwSetKeyCallback(). Now, if we only could connect static methods with regular methods somehow...
C++11 Event driven approach with statics and lambdas
The best solution I could find out is the following. It works and is somewhat elegant, but I still do not consider it perfect. Let's look at it and discuss:
void Presentation::initGLFW()
{
glfwInit();
static auto callback_static = [this](
GLFWwindow* window, int key, int scancode, int action, int mods) {
// because we have a this pointer we are now able to call a non-static member method:
key_callbackMember(window, key, scancode, action, mods);
};
glfwSetKeyCallback(window,
[](GLFWwindow* window, int key, int scancode, int action, int mods)
{
// only static methods can be called here as we cannot change glfw function parameter list to include instance pointer
callback_static(window, key, scancode, action, mods);
}
);
}
void Presentation::key_callbackMember(GLFWwindow* window, int key, int scancode, int action, int mods)
{
// we can now call anywhere in our code to process the key input:
app->handleInput(key, action);
}
The definition of callback_static is where we connect a static object with instance data, in this case this is an instance of our Presentation class. You can read the definition as follows: If callback_static is called anytime after this definition, all parameters will be passed to the member method key_callbackMember called at the Presentation instance just used. This definition has nothing to do with the GLFW library yet - it is just the preparation for the next step.
We now use a second lambda to register our callback with the library in glfwSetKeyCallback(). Again, if callback_static would not have been defined as static we could not pass it to GLFW here.
This is what happens at runtime after all the initializations, when GLFW calls our code:
GLFW recognizes a key event and calls our static object callback_static
callback_static has access to an instance of Presentation class and calls it's instance method key_callbackMember
Now that we are in 'object world' we can process the key event somewhere else. In this case we call the method handleInput on some arbitrary object app, that has been setup somewhere else in our code.
The good: We have achieved what we wanted with no need to define global objects outside our initialization method initGLFW. No need for C style globals.
The bad: Don't be fooled just because everything is neatly packed into one method. We still have static objects. And with them all the problems global objects have. E.g. multiple calls to our initialization method (with different instances of Presentation) would probably not have the effect you intended.
Summary
It is possible to connect C style callbacks of existing libraries to instances of classes in your own code. You can try to minimize houeskeeping code by defining the necessary objects in member methods of your code. But you still need one static object for each callback. If you want to connect several instances of your C++ code with a C style callback be prepared to introduce a more complicated management of your static objects than in the example above.
Hope this helps someone. Happy coding.
I can see that the init has the following override:
Init(CALLBACK_FUNC_EX callback_func, void * callback_parm)
where CALLBACK_FUNC_EX is
typedef void (*CALLBACK_FUNC_EX)(int, void *);
The type of pointer to non-static member function is different from pointer to ordinary function.
Type is void(*)(int) if it’s an ordinary or static member function.
Type is void(CLoggersInfra::*)(int) if it’s a non-static member function.
So you cannot pass a pointer to a non-static member function if it is expecting an ordinary function pointer.
Furthermore, a non-static member function has an implicit/hidden parameter to the object. The this pointer is implicitly passed as an argument to the member function call. So the member functions can be invoked only by providing an object.
If the API Init cannot be changed, a wrapper function (ordinary function or a class static member function) that invokes the member can be used. In the worst case, the object would be a global for the wrapper function to access.
CLoggersInfra* pLoggerInfra;
RedundencyManagerCallBackWrapper(int val)
{
pLoggerInfra->RedundencyManagerCallBack(val);
}
m_cRedundencyManager->Init(RedundencyManagerCallBackWrapper);
If the API Init can be changed, there are many alternatives - Object non-static member function pointer, Function Object, std::function or Interface Function.
See the post on callbacks for the different variations with C++ working examples.
This question and answer from the C++ FAQ Lite covers your question and the considerations involved in the answer quite nicely I think. Short snippet from the web page I linked:
Don’t.
Because a member function is meaningless without an object to invoke
it on, you can’t do this directly (if The X Window System was
rewritten in C++, it would probably pass references to objects around,
not just pointers to functions; naturally the objects would embody the
required function and probably a whole lot more).
There's surprisingly a simple way to do so in c++14 or above:
auto callback = [this](){ this->methodCB(); };
subscribeToEvent(callback);
**assuming subscribeToEvent gets std::function<void()>
Looks like std::mem_fn (C++11) does exactly what you need:
Function template std::mem_fn generates wrapper objects for pointers to members, which can store, copy, and invoke a pointer to member. Both references and pointers (including smart pointers) to an object can be used when invoking a std::mem_fn.

Using class member function pointers in C++ for Arduino

I need to make a list of function pointers to member objects and then execute them as need be in an InterruptSubRoutine. I created a class with a virtual function to wrap all classes that need interrupts, and they will use to execute their interrupt.
I can pass these and put them in the Array, but I get an error on the line where I try to execute them saying
expression must have a (pointer-to-) function type.
Header
typedef bool (InterruptSubRoutine::*function_pointer)();
void initializeTI();
void enableTI();
void disableTI();
void procInterrupt();
void addInterrupt(bool (InterruptSubRoutine::*interrupt)());
TimerThree timerInt;
function_pointer activeInterrupts[INTERRUPT_POINTER_SIZE];
Cpp
void ::initializeTI()
{
timerInt.initialize(TIMER_INTERRUPT_PERIOD);
}
void ::procInterrupt()
{
bool empty = true;
for(int i = 0; i<INTERRUPT_POINTER_SIZE; i++)
{
if (activeInterrupts[i] != nullptr)
{
empty = false;
bool returnV = activeInterrupts[i](); //this is where i get the problem, with the error stating "expression must have a (pointer-to-) function type"
if (!returnV)
{
activeInterrupts[i] = nullptr;
}
}
}
if (empty)
{
disableTI();
}
}
void ::addInterrupt(bool (InterruptSubRoutine::*function)())
{
for(int i = 0; i<INTERRUPT_POINTER_SIZE; i++)
{
if (activeInterrupts[i] == nullptr)
{
activeInterrupts[i] = function;
break;
}
}
}
void ::enableTI()
{
void (*interrupt)(void);
interrupt = &procInterrupt;
timerInt.attachInterrupt(interrupt, TIMER_INTERRUPT_PERIOD);
}
void ::disableTI()
{
timerInt.detachInterrupt();
}
here's something to get you started:
activeInterrupts is an array of function pointers
function_pointer activeInterrupts[INTERRUPT_POINTER_SIZE]; hence activeInterrupts[i] will be a function pointer.
you can't assign a integer-type variable, a function pointer: bool returnV = activeInterrupts[i](), they are incompatible types
Your problem starts with the wording of the question:
I need to make a list of function pointers to member objects...
No! You have pointer to member functions! And member functions need a object in which they are executed.
I created a class with a virtual function to wrap all classes that need interrupts
No! You create a base class where instances from derived classes ( which are called objects ) can use the given member functions. Please remember: The methods are part of the class but they are running in the context of the object.
Instead of that you also can have static class functions which are related to the class and work without objects! This is also possible but a total different approach.
From your wording I believe you did not really understand what is class,method,object and the relations between them. So I would advice you to read a OOP beginners book.
The simple problem as result of your wrong coding is, that you need an object in which context you can call the member function ( method ) which is addressed via a member function pointer.
If you want to store a object and a pointer, simply use a struct to fill the pointer and the object in and do the call. You are also free to bind the method pointer to the object with std::bind if you are using a modern c++11 version. As std::bind is header only code from c++ it works also for avr.
In general:
I think it is a bad design for small embedded systems to create, register, and store objects and in addition pointers to functions in runtime! this all can be done during compile time which makes the code much faster, smaller and less error prone. Think about memory allocation ( new/malloc) on a small embedded device! And if you are already use static allocation and global objects ( which is also bad design in bigger projects ) you also can resolve your call tree to all objects during compile time.
As a simple fix for your first problem you should:
bool returnV = (object.*activeInterrupts[i])();
where object is an instance of InterruptSubRoutine class or any derived class from that.
As an additional remark to your question itself:
It would be nice to shrink down all code snippets to the minimum we need to analyze the problem. On the other hand it would be nice if it could be used to compile it directly without adding all the missing stuff. Thanks!

How can I pass a class member function as a callback?

I'm using an API that requires me to pass a function pointer as a callback. I'm trying to use this API from my class but I'm getting compilation errors.
Here is what I did from my constructor:
m_cRedundencyManager->Init(this->RedundencyManagerCallBack);
This doesn't compile - I get the following error:
Error 8 error C3867: 'CLoggersInfra::RedundencyManagerCallBack': function call missing argument list; use '&CLoggersInfra::RedundencyManagerCallBack' to create a pointer to member
I tried the suggestion to use &CLoggersInfra::RedundencyManagerCallBack - didn't work for me.
Any suggestions/explanation for this??
I'm using VS2008.
Thanks!!
This is a simple question but the answer is surprisingly complex. The short answer is you can do what you're trying to do with std::bind1st or boost::bind. The longer answer is below.
The compiler is correct to suggest you use &CLoggersInfra::RedundencyManagerCallBack. First, if RedundencyManagerCallBack is a member function, the function itself doesn't belong to any particular instance of the class CLoggersInfra. It belongs to the class itself. If you've ever called a static class function before, you may have noticed you use the same SomeClass::SomeMemberFunction syntax. Since the function itself is 'static' in the sense that it belongs to the class rather than a particular instance, you use the same syntax. The '&' is necessary because technically speaking you don't pass functions directly -- functions are not real objects in C++. Instead you're technically passing the memory address for the function, that is, a pointer to where the function's instructions begin in memory. The consequence is the same though, you're effectively 'passing a function' as a parameter.
But that's only half the problem in this instance. As I said, RedundencyManagerCallBack the function doesn't 'belong' to any particular instance. But it sounds like you want to pass it as a callback with a particular instance in mind. To understand how to do this you need to understand what member functions really are: regular not-defined-in-any-class functions with an extra hidden parameter.
For example:
class A {
public:
A() : data(0) {}
void foo(int addToData) { this->data += addToData; }
int data;
};
...
A an_a_object;
an_a_object.foo(5);
A::foo(&an_a_object, 5); // This is the same as the line above!
std::cout << an_a_object.data; // Prints 10!
How many parameters does A::foo take? Normally we would say 1. But under the hood, foo really takes 2. Looking at A::foo's definition, it needs a specific instance of A in order for the 'this' pointer to be meaningful (the compiler needs to know what 'this' is). The way you usually specify what you want 'this' to be is through the syntax MyObject.MyMemberFunction(). But this is just syntactic sugar for passing the address of MyObject as the first parameter to MyMemberFunction. Similarly, when we declare member functions inside class definitions we don't put 'this' in the parameter list, but this is just a gift from the language designers to save typing. Instead you have to specify that a member function is static to opt out of it automatically getting the extra 'this' parameter. If the C++ compiler translated the above example to C code (the original C++ compiler actually worked that way), it would probably write something like this:
struct A {
int data;
};
void a_init(A* to_init)
{
to_init->data = 0;
}
void a_foo(A* this, int addToData)
{
this->data += addToData;
}
...
A an_a_object;
a_init(0); // Before constructor call was implicit
a_foo(&an_a_object, 5); // Used to be an_a_object.foo(5);
Returning to your example, there is now an obvious problem. 'Init' wants a pointer to a function that takes one parameter. But &CLoggersInfra::RedundencyManagerCallBack is a pointer to a function that takes two parameters, it's normal parameter and the secret 'this' parameter. That's why you're still getting a compiler error (as a side note: If you've ever used Python, this kind of confusion is why a 'self' parameter is required for all member functions).
The verbose way to handle this is to create a special object that holds a pointer to the instance you want and has a member function called something like 'run' or 'execute' (or overloads the '()' operator) that takes the parameters for the member function, and simply calls the member function with those parameters on the stored instance. But this would require you to change 'Init' to take your special object rather than a raw function pointer, and it sounds like Init is someone else's code. And making a special class for every time this problem comes up will lead to code bloat.
So now, finally, the good solution, boost::bind and boost::function, the documentation for each you can find here:
boost::bind docs,
boost::function docs
boost::bind will let you take a function, and a parameter to that function, and make a new function where that parameter is 'locked' in place. So if I have a function that adds two integers, I can use boost::bind to make a new function where one of the parameters is locked to say 5. This new function will only take one integer parameter, and will always add 5 specifically to it. Using this technique, you can 'lock in' the hidden 'this' parameter to be a particular class instance, and generate a new function that only takes one parameter, just like you want (note that the hidden parameter is always the first parameter, and the normal parameters come in order after it). Look at the boost::bind docs for examples, they even specifically discuss using it for member functions. Technically there is a standard function called [std::bind1st][3] that you could use as well, but boost::bind is more general.
Of course, there's just one more catch. boost::bind will make a nice boost::function for you, but this is still technically not a raw function pointer like Init probably wants. Thankfully, boost provides a way to convert boost::function's to raw pointers, as documented on StackOverflow here. How it implements this is beyond the scope of this answer, though it's interesting too.
Don't worry if this seems ludicrously hard -- your question intersects several of C++'s darker corners, and boost::bind is incredibly useful once you learn it.
C++11 update: Instead of boost::bind you can now use a lambda function that captures 'this'. This is basically having the compiler generate the same thing for you.
That doesn't work because a member function pointer cannot be handled like a normal function pointer, because it expects a "this" object argument.
Instead you can pass a static member function as follows, which are like normal non-member functions in this regard:
m_cRedundencyManager->Init(&CLoggersInfra::Callback, this);
The function can be defined as follows
static void Callback(int other_arg, void * this_pointer) {
CLoggersInfra * self = static_cast<CLoggersInfra*>(this_pointer);
self->RedundencyManagerCallBack(other_arg);
}
This answer is a reply to a comment above and does not work with VisualStudio 2008 but should be preferred with more recent compilers.
Meanwhile you don't have to use a void pointer anymore and there is also no need for boost since std::bind and std::function are available. One advantage (in comparison to void pointers) is type safety since the return type and the arguments are explicitly stated using std::function:
// std::function<return_type(list of argument_type(s))>
void Init(std::function<void(void)> f);
Then you can create the function pointer with std::bind and pass it to Init:
auto cLoggersInfraInstance = CLoggersInfra();
auto callback = std::bind(&CLoggersInfra::RedundencyManagerCallBack, cLoggersInfraInstance);
Init(callback);
Complete example for using std::bind with member, static members and non member functions:
#include <functional>
#include <iostream>
#include <string>
class RedundencyManager // incl. Typo ;-)
{
public:
// std::function<return_type(list of argument_type(s))>
std::string Init(std::function<std::string(void)> f)
{
return f();
}
};
class CLoggersInfra
{
private:
std::string member = "Hello from non static member callback!";
public:
static std::string RedundencyManagerCallBack()
{
return "Hello from static member callback!";
}
std::string NonStaticRedundencyManagerCallBack()
{
return member;
}
};
std::string NonMemberCallBack()
{
return "Hello from non member function!";
}
int main()
{
auto instance = RedundencyManager();
auto callback1 = std::bind(&NonMemberCallBack);
std::cout << instance.Init(callback1) << "\n";
// Similar to non member function.
auto callback2 = std::bind(&CLoggersInfra::RedundencyManagerCallBack);
std::cout << instance.Init(callback2) << "\n";
// Class instance is passed to std::bind as second argument.
// (heed that I call the constructor of CLoggersInfra)
auto callback3 = std::bind(&CLoggersInfra::NonStaticRedundencyManagerCallBack,
CLoggersInfra());
std::cout << instance.Init(callback3) << "\n";
}
Possible output:
Hello from non member function!
Hello from static member callback!
Hello from non static member callback!
Furthermore using std::placeholders you can dynamically pass arguments to the callback (e.g. this enables the usage of return f("MyString"); in Init if f has a string parameter).
What argument does Init take? What is the new error message?
Method pointers in C++ are a bit difficult to use. Besides the method pointer itself, you also need to provide an instance pointer (in your case this). Maybe Init expects it as a separate argument?
A pointer to a class member function is not the same as a pointer to a function. A class member takes an implicit extra argument (the this pointer), and uses a different calling convention.
If your API expects a nonmember callback function, that's what you have to pass to it.
Is m_cRedundencyManager able to use member functions? Most callbacks are set up to use regular functions or static member functions. Take a look at this page at C++ FAQ Lite for more information.
Update: The function declaration you provided shows that m_cRedundencyManager is expecting a function of the form: void yourCallbackFunction(int, void *). Member functions are therefore unacceptable as callbacks in this case. A static member function may work, but if that is unacceptable in your case, the following code would also work. Note that it uses an evil cast from void *.
// in your CLoggersInfra constructor:
m_cRedundencyManager->Init(myRedundencyManagerCallBackHandler, this);
// in your CLoggersInfra header:
void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr);
// in your CLoggersInfra source file:
void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr)
{
((CLoggersInfra *)CLoggersInfraPtr)->RedundencyManagerCallBack(i);
}
Necromancing.
I think the answers to date are a little unclear.
Let's make an example:
Supposed you have an array of pixels (array of ARGB int8_t values)
// A RGB image
int8_t* pixels = new int8_t[1024*768*4];
Now you want to generate a PNG.
To do so, you call the function toJpeg
bool ok = toJpeg(writeByte, pixels, width, height);
where writeByte is a callback-function
void writeByte(unsigned char oneByte)
{
fputc(oneByte, output);
}
The problem here: FILE* output has to be a global variable.
Very bad if you're in a multithreaded environment (e.g. a http-server).
So you need some way to make output a non-global variable, while retaining the callback signature.
The immediate solution that springs into mind is a closure, which we can emulate using a class with a member function.
class BadIdea {
private:
FILE* m_stream;
public:
BadIdea(FILE* stream) {
this->m_stream = stream;
}
void writeByte(unsigned char oneByte){
fputc(oneByte, this->m_stream);
}
};
And then do
FILE *fp = fopen(filename, "wb");
BadIdea* foobar = new BadIdea(fp);
bool ok = TooJpeg::writeJpeg(foobar->writeByte, image, width, height);
delete foobar;
fflush(fp);
fclose(fp);
However, contrary to expectations, this does not work.
The reason is, C++ member functions are kinda implemented like C# extension functions.
So you have
class/struct BadIdea
{
FILE* m_stream;
}
and
static class BadIdeaExtensions
{
public static writeByte(this BadIdea instance, unsigned char oneByte)
{
fputc(oneByte, instance->m_stream);
}
}
So when you want to call writeByte, you need pass not only the address of writeByte, but also the address of the BadIdea-instance.
So when you have a typedef for the writeByte procedure, and it looks like this
typedef void (*WRITE_ONE_BYTE)(unsigned char);
And you have a writeJpeg signature that looks like this
bool writeJpeg(WRITE_ONE_BYTE output, uint8_t* pixels, uint32_t
width, uint32_t height))
{ ... }
it's fundamentally impossible to pass a two-address member function to a one-address function pointer (without modifying writeJpeg), and there's no way around it.
The next best thing that you can do in C++, is using a lambda-function:
FILE *fp = fopen(filename, "wb");
auto lambda = [fp](unsigned char oneByte) { fputc(oneByte, fp); };
bool ok = TooJpeg::writeJpeg(lambda, image, width, height);
However, because lambda is doing nothing different, than passing an instance to a hidden class (such as the "BadIdea"-class), you need to modify the signature of writeJpeg.
The advantage of lambda over a manual class, is that you just need to change one typedef
typedef void (*WRITE_ONE_BYTE)(unsigned char);
to
using WRITE_ONE_BYTE = std::function<void(unsigned char)>;
And then you can leave everything else untouched.
You could also use std::bind
auto f = std::bind(&BadIdea::writeByte, &foobar);
But this, behind the scene, just creates a lambda function, which then also needs the change in typedef.
So no, there is no way to pass a member function to a method that requires a static function-pointer.
But lambdas are the easy way around, provided that you have control over the source.
Otherwise, you're out of luck.
There's nothing you can do with C++.
Note:
std::function requires #include <functional>
However, since C++ allows you to use C as well, you can do this with libffcall in plain C, if you don't mind linking a dependency.
Download libffcall from GNU (at least on ubuntu, don't use the distro-provided package - it is broken), unzip.
./configure
make
make install
gcc main.c -l:libffcall.a -o ma
main.c:
#include <callback.h>
// this is the closure function to be allocated
void function (void* data, va_alist alist)
{
int abc = va_arg_int(alist);
printf("data: %08p\n", data); // hex 0x14 = 20
printf("abc: %d\n", abc);
// va_start_type(alist[, return_type]);
// arg = va_arg_type(alist[, arg_type]);
// va_return_type(alist[[, return_type], return_value]);
// va_start_int(alist);
// int r = 666;
// va_return_int(alist, r);
}
int main(int argc, char* argv[])
{
int in1 = 10;
void * data = (void*) 20;
void(*incrementer1)(int abc) = (void(*)()) alloc_callback(&function, data);
// void(*incrementer1)() can have unlimited arguments, e.g. incrementer1(123,456);
// void(*incrementer1)(int abc) starts to throw errors...
incrementer1(123);
// free_callback(callback);
return EXIT_SUCCESS;
}
And if you use CMake, add the linker library after add_executable
add_library(libffcall STATIC IMPORTED)
set_target_properties(libffcall PROPERTIES
IMPORTED_LOCATION /usr/local/lib/libffcall.a)
target_link_libraries(BitmapLion libffcall)
or you could just dynamically link libffcall
target_link_libraries(BitmapLion ffcall)
Note:
You might want to include the libffcall headers and libraries, or create a cmake project with the contents of libffcall.
A simple solution "workaround" still is to create a class of virtual functions "interface" and inherit it in the caller class. Then pass it as a parameter "could be in the constructor" of the other class that you want to call your caller class back.
DEFINE Interface:
class CallBack
{
virtual callMeBack () {};
};
This is the class that you want to call you back:
class AnotherClass ()
{
public void RegisterMe(CallBack *callback)
{
m_callback = callback;
}
public void DoSomething ()
{
// DO STUFF
// .....
// then call
if (m_callback) m_callback->callMeBack();
}
private CallBack *m_callback = NULL;
};
And this is the class that will be called back.
class Caller : public CallBack
{
void DoSomthing ()
{
}
void callMeBack()
{
std::cout << "I got your message" << std::endl;
}
};
It is still difficult to connect C style callback functions with C++ class instances. I want to kind of rephrase the original question:
Some library you are using requires a C style function to be called back from that library. Changing the library API is out of the question since it is not your API.
You want the callback to be handled in your own C++ code in member methods
As you did not mention (exactly) what callback you want to handle I will give an example using GLFW callbacks for key input. (On a side note: I know GLFW offers some other mechanism to attach user data to their API, but that is not the topic here.)
I don't know any solution to this problem that doesn't include usage of some kind of static object. Let's look at our options:
Simple approach: Use C style global objects
As we always think in classes and instances we sometimes forget that in C++ we still have the whole arsenal of C at our hands. So sometimes this very simple solution does not come to mind.
Let's assume we have a class Presentation that should handle keyboard input. This could look like this:
struct KeyInput {
int pressedKey;
} KeyInputGlobal;
void globalKeyHandler(GLFWwindow* window, int key, int scancode, int action, int mods) {
KeyInputGlobal.pressedKey = key;
}
int Presentation::getCurrentKey()
{
return KeyInputGlobal.pressedKey;
}
void Presentation::initGLFW()
{
glfwInit();
glfwSetKeyCallback(window, globalKeyHandler);
}
We have a global Object KeyInputGlobal that should receive the key pressed. The function globalKeyHandler has exactly the C style API signature needed by the GLFW library to be able to call our code. It is activated on our member method initGLFW. If anywhere in our code we are interested in the currently pressed key we can just call the other member method Presentation::getCurrentKey
What is wrong with this approach?
Maybe it is all fine. Depends entirely on your use case. Maybe you are totally fine to just read the last pressed key somwhere in your application code. You don't care to have missed key pressed events. The simple approach is all you need.
To generalize: If you are able to fully process the callback in C style code, calculate some result and store it in a global object to be read later from other parts of your code, then it may indeed make sense to use this simple approach. On the plus side: It is very simple to understand. The downside? It feels a little bit like cheating, because you didn't really process the callback in your C++ code, you just used the results. If you think of the callback as an event and want each event to be properly processed in your member methods this approch won't be enough.
Another simple approach: Use C++ static objects
I guess many of us have already done this. Certainly I have. Thinking: Wait, we have a C++ concept of globals, that is using static. But we can keep the discussion short here: It may be more C++ style than using the C style from previous example, but the problems are the same - we still have globals, that are hard to bring together with non-static, regular member methods. For completeness, it would look like this in our class declaration:
class Presentation
{
public:
struct KeyInput {
int pressedKey;
};
static KeyInput KeyInputGlobal;
static void globalKeyHandler(GLFWwindow* window, int key, int scancode, int action, int mods) {
KeyInputGlobal.pressedKey = key;
}
int getCurrentKey()
{
return KeyInputGlobal.pressedKey;
}
...
}
Activating our callback would look the same, but we also have to define the static struct that receives the key pressed in our implementation:
void Presentation::initGLFW()
{
glfwInit();
glfwSetKeyCallback(window, globalKeyHandler);
}
//static
Presentation::KeyInput Presentation::KeyInputGlobal;
You might be inclined to just remove the static keyword from our callback method globalKeyHandler: The compiler will immediately tell you that you can no longer pass this to GLFW in glfwSetKeyCallback(). Now, if we only could connect static methods with regular methods somehow...
C++11 Event driven approach with statics and lambdas
The best solution I could find out is the following. It works and is somewhat elegant, but I still do not consider it perfect. Let's look at it and discuss:
void Presentation::initGLFW()
{
glfwInit();
static auto callback_static = [this](
GLFWwindow* window, int key, int scancode, int action, int mods) {
// because we have a this pointer we are now able to call a non-static member method:
key_callbackMember(window, key, scancode, action, mods);
};
glfwSetKeyCallback(window,
[](GLFWwindow* window, int key, int scancode, int action, int mods)
{
// only static methods can be called here as we cannot change glfw function parameter list to include instance pointer
callback_static(window, key, scancode, action, mods);
}
);
}
void Presentation::key_callbackMember(GLFWwindow* window, int key, int scancode, int action, int mods)
{
// we can now call anywhere in our code to process the key input:
app->handleInput(key, action);
}
The definition of callback_static is where we connect a static object with instance data, in this case this is an instance of our Presentation class. You can read the definition as follows: If callback_static is called anytime after this definition, all parameters will be passed to the member method key_callbackMember called at the Presentation instance just used. This definition has nothing to do with the GLFW library yet - it is just the preparation for the next step.
We now use a second lambda to register our callback with the library in glfwSetKeyCallback(). Again, if callback_static would not have been defined as static we could not pass it to GLFW here.
This is what happens at runtime after all the initializations, when GLFW calls our code:
GLFW recognizes a key event and calls our static object callback_static
callback_static has access to an instance of Presentation class and calls it's instance method key_callbackMember
Now that we are in 'object world' we can process the key event somewhere else. In this case we call the method handleInput on some arbitrary object app, that has been setup somewhere else in our code.
The good: We have achieved what we wanted with no need to define global objects outside our initialization method initGLFW. No need for C style globals.
The bad: Don't be fooled just because everything is neatly packed into one method. We still have static objects. And with them all the problems global objects have. E.g. multiple calls to our initialization method (with different instances of Presentation) would probably not have the effect you intended.
Summary
It is possible to connect C style callbacks of existing libraries to instances of classes in your own code. You can try to minimize houeskeeping code by defining the necessary objects in member methods of your code. But you still need one static object for each callback. If you want to connect several instances of your C++ code with a C style callback be prepared to introduce a more complicated management of your static objects than in the example above.
Hope this helps someone. Happy coding.
I can see that the init has the following override:
Init(CALLBACK_FUNC_EX callback_func, void * callback_parm)
where CALLBACK_FUNC_EX is
typedef void (*CALLBACK_FUNC_EX)(int, void *);
The type of pointer to non-static member function is different from pointer to ordinary function.
Type is void(*)(int) if it’s an ordinary or static member function.
Type is void(CLoggersInfra::*)(int) if it’s a non-static member function.
So you cannot pass a pointer to a non-static member function if it is expecting an ordinary function pointer.
Furthermore, a non-static member function has an implicit/hidden parameter to the object. The this pointer is implicitly passed as an argument to the member function call. So the member functions can be invoked only by providing an object.
If the API Init cannot be changed, a wrapper function (ordinary function or a class static member function) that invokes the member can be used. In the worst case, the object would be a global for the wrapper function to access.
CLoggersInfra* pLoggerInfra;
RedundencyManagerCallBackWrapper(int val)
{
pLoggerInfra->RedundencyManagerCallBack(val);
}
m_cRedundencyManager->Init(RedundencyManagerCallBackWrapper);
If the API Init can be changed, there are many alternatives - Object non-static member function pointer, Function Object, std::function or Interface Function.
See the post on callbacks for the different variations with C++ working examples.
This question and answer from the C++ FAQ Lite covers your question and the considerations involved in the answer quite nicely I think. Short snippet from the web page I linked:
Don’t.
Because a member function is meaningless without an object to invoke
it on, you can’t do this directly (if The X Window System was
rewritten in C++, it would probably pass references to objects around,
not just pointers to functions; naturally the objects would embody the
required function and probably a whole lot more).
There's surprisingly a simple way to do so in c++14 or above:
auto callback = [this](){ this->methodCB(); };
subscribeToEvent(callback);
**assuming subscribeToEvent gets std::function<void()>
Looks like std::mem_fn (C++11) does exactly what you need:
Function template std::mem_fn generates wrapper objects for pointers to members, which can store, copy, and invoke a pointer to member. Both references and pointers (including smart pointers) to an object can be used when invoking a std::mem_fn.