Keep a shared library from using its own exports - c++

Good evening,
I have a library that imports another library which exports a function, lets call it foo(). I want my library to serve as a wrapper for the other library. That means, I want my library to export a function foo() which internally calls the function foo() from the other library. Something like this:
myfoo.hpp:
__attribute__((visibility("default"))) void foo(); //my foo() export
myfoo.cpp:
#include "myfoo.hpp"
#include "wrapperfoo.hpp"
void foo()
{
wrapperfoo();
}
wrapperfoo.cpp:
#include "wrapperfoo.hpp"
#include "theotherapifoo.hpp"
void wrapperfoo()
{
::foo(); //PROBLEM!! This seems to call my own exported foo from myfoo.hpp!!!
}
The problem is that both dynamic libraries get linked into the executable and my wrapperfunction seems to recursively call my own exported foo function over and over despite wrapperfoo.cpp not including myfoo.hpp!
What can I do to prevent this from happening and access the other libraries foo()?

One workaround would be to dynamically link the library using dlopen() or similar.
#include <cstring>
#include <dlfcn.h>
#include <stdexcept>
struct OriginalLibrary {
using FunPtr = void(*)();
OriginalLibrary()
: m_lib([] {
if (void * const lib = dlopen("libdl.so", RTLD_NOW))
return lib;
throw std::runtime_error(dlerror());
}())
, m_foo(getFunSym("foo"))
{}
~OriginalLibrary() noexcept { dlclose(m_lib); }
FunPtr getFunSym(char const * const name) {
if (void * const sym = dlsym(m_lib, name)) {
FunPtr f;
// Assuming function and data pointers are of
// same size and binary-compatible on your arch:
std::memcpy(&f, &sym, sizeof(f));
return f;
}
throw std::runtime_error(dlerror());
}
void * const m_lib;
void (* m_foo)();
};
// WARNING! Global symbol! (you might want to solve this in some other manner)
OriginalLibrary original;
void foo() { return original.m_foo(); }

Related

Callback functions in C++ dynamic linked library

I have a dynamic linked library in C++. What I want to do is have a callback function declared in the library and leave it to the user to define in their code that uses the library. Pseudo-code example:
//in library
void userDefinedFunction();
void libraryFunction() {
//do stuff
userDefinedFunction();
//do more stuff
}
//in user code
void userDefinedFunction() {
//user-specific code
}
Is this possible in modern C++?
Of course. Your library could accept a function pointer to a user defined function or a reference to a functor given by the user. The void libraryFunction() will just use that to call the user function.
You can use std::function from functional library. Here is an example with lambda expression and function
#include <iostream>
#include <functional>
std::function<int (int)> func;
int testfunc(int i)
{
std::cout<<"testfunc function called ";
return i+7;
}
void process()
{
if (func)
std::cout<<func(3)<<std::endl;
}
int main()
{
process();
func = [](int i) {
std::cout<<"Lambda function called ";
return i+4;
};
process();
func = testfunc;
process();
return 0;
}

Passing a pointer to a C++ member function to a C API library

First post here and I've tried to look at previous similar posts but none of them seem to work or do quite what I want.
I have some C code, call it library.c. I've removed a lot of the code and simplified it.
// libary.c
// A callback function that takes an int
void (*library_cb)(int);
void init(void (*cb())) {
// some other code
library_cb = cb;
}
void sample() {
int data;
// execute a bunch of code and then call the callback function
(*library_cb)(data);
}
Now I have c++ code that defines the callback function that I want to pass to the code in library.c
// someclass.cpp
class SomeClass {
public:
SomeClass() {
};
~SomeClass() {
};
void callback(int data) {
// Do some stuff
}
};
And then in main.cpp I want to do something like
// main.cpp
extern "C" {
#include "library.h"
}
#include "someclass.h"
SomeClass some_class;
int main() {
init(&some_class.callback) // obviously doesn't work
while(true) {
sample(); // this would call callback in SomeClass
}
}
Now I know one solution is to define callback as
static void callback(int data)
But I was wondering if there are any other ways to do this. From what I read, std::function might help or std::mem_fn. But I can't seem to figure out how.
I haven't included the header files and I wrote this code as an example of my problem so there might be some syntax errors, but hopefully the question/goal is clear.
Edit:
I should have mentioned that I can edit the c library.
Reading the answers, it seems I can change the c library to also accept a void* pointer to the class object to get this to work. Could someone show me an example for this case please? I'm super new to interfacing c code with c++.
Passing a pointer to a C++ member function to a C API library
... is not possible.
From what I read, std::function might help or std::mem_fn
Neither of those can be called in C either, but keep reading 'till the end.
C only has regular non-member function pointers so those are the only function pointers that a C program can call. In C++, such pointer can point to either a free function or a static member function.
Within the C++ implementation of such static- or non-member function you can of course do anything within the power of C++ (although, letting an exception escape the function would be bad), so you can indeed call a non-static member function there.
But to call a non-static member function, there needs to be an instance. A static object is a trivial solution, but is not very flexible and only useful in a few situations.
Well designed callback API's in C let user of the API register a generic data pointer (i.e. void*) in addition to a function pointer, and that data pointer will be forwarded to the callback. This design allows the callbacks to be stateful - the state is stored in the pointed object. When using such C API, you can pass a pointer to an object whose member functions the callback can then call. Or, you could pass a data pointer to a std::function or some other stateful type erasing function wrapper, and use a generic free function that simply forwards the call to the wrapper.
Your C API is not very usable. Here's how I'd do it:
The callback must at least take a user-provided void* parameter that the library doesn't interpret in any way. Without this parameter, callbacks are useless. Yes, they really are useless and the users of your API users will hate you for that.
If you want the callback to be able to modify the value of its parameter, you can pass the address of the void* parameter. That is useful for e.g. allocation-on-registration and similar uses where the parameter changes during callback's execution. This makes the library completely decoupled from the use of the pointer: not only it doesn't interpret the pointer, but it doesn't keep its value constant.
The library API symbols are all prefixed to prevent collisions in the global namespace.
Typedefs are used as needed to ensure readable code. Typing out function pointer types is tedious at best.
The header is guarded against multiple-inclusion, i.e. it must be OK to include it multiple times in a translation unit, without any errors.
The header declares a C interface when compiled in a C++ translation unit, since, well: the interface is a C one. C++ mangles the symbol names and the header will declare binary-incompatible symbols.
The header declares the C interface noexcept in C++11. This presents optimization opportunities to the C++ users.
Consider the library registering more than one callback, as well as possibly invoking the callback on registration and deregistration: those make interoperation with other programming languages much easier.
library.h - usable from C and C++
#pragma once
#ifdef __cplusplus
extern "C" {
#pragma GCC diagnostic push
// clang erroneously issues a warning in spite of extern "C" linkage
#pragma GCC diagnostic ignored "-Wc++17-compat-mangling"
#endif
#ifndef LIBRARY_NOEXCEPT
#if __cplusplus >= 201103L
// c.f. https://stackoverflow.com/q/24362616/1329652
#define LIBRARY_NOEXCEPT noexcept
#else
#define LIBRARY_NOEXCEPT
#endif
#endif
enum library_register_enum { LIBRARY_REG_FAILURE = 0, LIBRARY_REG_SUCCESS = 1, LIBRARY_REG_DUPLICATE = -1 };
enum library_call_enum { LIBRARY_SAMPLE, LIBRARY_REGISTER, LIBRARY_DEREGISTER };
typedef enum library_register_enum library_register_result;
typedef enum library_call_enum library_call_type;
#if __cplusplus >= 201103L
void library_callback_dummy(library_call_type, int, void**) LIBRARY_NOEXCEPT;
using library_callback = decltype(&library_callback_dummy);
#else
typedef void (*library_callback)(library_call_type, int, void**);
#endif
void library_init(void) LIBRARY_NOEXCEPT;
library_register_result library_register_callback(library_callback cb, void *cb_param) LIBRARY_NOEXCEPT;
void library_deregister_callback(library_callback cb, void *cb_param) LIBRARY_NOEXCEPT;
void library_deregister_any_callback(library_callback cb) LIBRARY_NOEXCEPT;
void library_deregister_all_callbacks(void) LIBRARY_NOEXCEPT;
void library_deinit(void) LIBRARY_NOEXCEPT;
void library_sample(void) LIBRARY_NOEXCEPT;
#ifdef __cplusplus
#pragma GCC diagnostic pop
}
#endif
Below note that the private data and functions, i.e. those not part of the API, are declared so (static).
library.c - the implementation
#include "library.h"
#include <stdlib.h>
typedef struct callback_s {
struct callback_s *next;
library_callback function;
void *parameter;
} callback;
static callback *cb_head;
void library_init(void) { /* some other code */
}
void library_deinit(void) { library_deregister_all_callbacks(); }
library_register_result library_register_callback(library_callback cb, void *cb_param) {
callback *el = cb_head;
while (el) {
if (el->function == cb && el->parameter == cb_param) return LIBRARY_REG_DUPLICATE;
el = el->next;
}
el = malloc(sizeof(callback));
if (!el) return LIBRARY_REG_FAILURE;
el->next = cb_head;
el->function = cb;
el->parameter = cb_param;
cb_head = el;
cb(LIBRARY_REGISTER, 0, &el->parameter);
return LIBRARY_REG_SUCCESS;
}
static int match_callback(const callback *el, library_callback cb, void *cb_param) {
return el && el->function == cb && el->parameter == cb_param;
}
static int match_any_callback(const callback *el, library_callback cb, void *cb_param) {
return el && el->function == cb;
}
static int match_all_callbacks(const callback *el, library_callback cb, void *cb_param) {
return !!el;
}
typedef int (*matcher)(const callback *, library_callback, void *);
static void deregister_callback(matcher match, library_callback cb, void *cb_param) {
callback **p = &cb_head;
while (*p) {
callback *el = *p;
if (match(el, cb, cb_param)) {
*p = el->next;
el->function(LIBRARY_DEREGISTER, 0, &el->parameter);
free(el);
} else
p = &el->next;
}
}
void library_deregister_callback(library_callback cb, void *cb_param) {
deregister_callback(match_callback, cb, cb_param);
}
void library_deregister_any_callback(library_callback cb) {
deregister_callback(match_any_callback, cb, NULL);
}
void library_deregister_all_callbacks(void) {
deregister_callback(match_all_callbacks, NULL, NULL);
}
void library_sample(void) {
int data = 42;
// execute a bunch of code and then call the callback function
callback *el = cb_head;
while (el) {
el->function(LIBRARY_SAMPLE, data, &el->parameter);
el = el->next;
}
}
That way, the user registering the callback can pass arbitrary data to the callback. The library-using code would be implemented in C++ as follows:
// https://github.com/KubaO/stackoverflown/tree/master/questions/c-cpp-library-api-53643120
#include <iostream>
#include <memory>
#include <string>
#include "library.h"
struct Data {
std::string payload;
static int counter;
void print(int value) {
++counter;
std::cout << counter << ": " << value << ", " << payload << std::endl;
}
};
int Data::counter;
extern "C" void callback1(library_call_type type, int value, void **param) noexcept {
if (type == LIBRARY_SAMPLE) {
auto *data = static_cast<Data *>(*param);
data->print(value);
}
}
using DataPrintFn = std::function<void(int)>;
extern "C" void callback2(library_call_type type, int value, void **param) noexcept {
assert(param && *param);
auto *fun = static_cast<DataPrintFn *>(*param);
if (type == LIBRARY_SAMPLE)
(*fun)(value);
else if (type == LIBRARY_DEREGISTER) {
delete fun;
*param = nullptr;
}
}
void register_callback(Data *data) {
library_register_callback(&callback1, data);
}
template <typename F>
void register_callback(F &&fun) {
auto f = std::make_unique<DataPrintFn>(std::forward<F>(fun));
library_deregister_callback(callback2, f.get());
library_register_callback(callback2, f.release());
// the callback will retain the functor
}
int main() {
Data data;
data.payload = "payload";
library_init();
register_callback(&data);
register_callback([&](int value) noexcept { data.print(value); });
library_sample();
library_sample();
library_deinit(); // must happen before the 'data' is destructed
assert(data.counter == 4);
}

static variables empty when using dynamic loading of library

I have this setup:
ClassA.h - belongs to libA.dll
class ClassA
{
public:
static std::vector<std::string> getStrings();
~ClassA();
static void addToVector(std::string s);
static void setAddAllowed(bool addAllowed);
private:
ClassA();
};
extern "C"
{
extern void addToStrings(std::string s);
}
ClassA.cpp
#include<ClassA.h>
#include<vector>
static std::vector<std::string> strings;
static bool addAllowed = false;
std::vector<std::string> ClassA::getStrings()
{
return strings;
}
void ClassA::addToVector(std::string s)
{
if (addAllowed)
{
strings.push_back(s);
}
}
void ClassA::setAddAllowed(bool add)
{
addAllowed = add;
}
extern void addToStrings(std::string s)
{
ClassA::addToVector(s);
}
ClassB.h - belongs to libB.dll
class ClassB
{
public:
static void addString(std::string s);
};
ClassB.cpp
#include<ClassB.h>
#include<ClassA.h> //not present if libA is dynamically loaded.
void ClassB::addString(std::string s)
{
addToStrings( s ); // problem if addToStrings is called with a function pointer obtained from dynamic loading of libA.dll - libB doesn't depend on libA actually.
}
ClassC.h
class ClassC
{
public:
static void setAddAllowed(bool add);
};
ClassC.cpp
#include<ClassA.h>
#include<ClassC.h>
void ClassC::setAddAllowed(bool addAllowed)
{
ClassA::setAddAllowed(addAllowed);
}
Main.cpp
int main()
{
ClassB::addString("example1");
ClassC::setAddAllowed( true );
ClassB::addString("example2");
ClassB::addString("example3");
std::vector<std::string> v = ClassA::getStrings();
}
with this setup, every thing works fine, I could get the strings in ClassA::getStrings(). But the problem appears - the vector is empty, if I add the strings in ClassB using function pointer obtained from dynamically loaded dll of libA. I get the symbol of extern function addToStrings as function pointer and make a call. In that case, the vector v is empty.
Example code for loading libA and calling the function:
typedef void (*addToStringsFP) (std::string s);
addToStringsFP fp = NULL;
Handle libHandle = NULL;
libHandle = LoadImage("libA",0);
fp = (addToStringsFP)FindSymbol(libHandle,"addToStrings");
This is only to demonstrate how I am loading libA and calling the function pointer. LoadImage, FindSymbol are similar to dlopen(), dlsym() - I can't post actual names.
What am I misunderstanding here ?
I found the answer.
The LoadImage function that I am using is loading a new image into the process instead of looking at already loaded dlls first and then load.
I had to use a different version of the LoadImage which loads the image that is currently in the process- basically a shared image. That solved the problem.
I thought it might be useful to someone who may have some problem albeit not much probable I think.

Exposing application API and data to DLL

I have a dll plugin ,myDLL.cpp, which has the following code:
#include "myDLL.h"
#include "MainApp.h"
class A{
public:
// NOTE: SomeType is defined in main application code.
A(SomeType* data) : m_data{data}
void MemberFunc(){
// NOTE: do_something should access data in main application.
m_data->do_something();
}
private:
SomeType* m_data;
};
// exported function
A* createInstance(SomeType* data){
return new A(data);
}
In the main application I have:
stc::vector<int> IntArray;
class SomeType{
SomeType(){
IntArray.resize(1000);
}
void do_something(){
// manipulate IntArray's contents.
IntArray[rand() % IntArray.size()] = rand();
}
};
typedef A*(_createInstance)(SomeType*);
void main(){
// Load the Dll and get createInstance()
_createInstance createInstance = LoadMyDLL();
SomeType someType;
A* a = createInstance(&someType);
a->MemberFunc();
// Free the instance of A and unload the DLL.
UnloadMyDLL(a);
}
The dll code now can use the API of the main application, but it can't access the right data. When I put a break point at m_data->do_something(); and enter the method call, then I see that IntArray is empty. What am I doing wrong and how do I solve the problem?
I could succesfully run your example without experiencing your problem:
I assumed that in your headers there are only the class definitions and not definition of its member functions
So I buid a DLL project. But it failed producing the dll because of the missing do_something() function. Normal, because with your architecture it should be defined in the application not in the DLL ! I could solve the problem by making do_something() virtual.
Then I build the application. I first chose for simplicity and linked the application with the DLL (no loading issues). Unfortunately it didn't find either MemberFunc() nor createInstance(). I could solve this by exporting the DLL entry.
FInally I updated the application, to have a dynamic load of the library. For avoiding unnecessary hassle of having to find back MemberFunc(), I made it virtual as well.
In all the tests above, I had absolutely no problem. IntArray was always correct. In debug mode I could see it with the expected content, as soon as it entered the scope.
My conclusion, from these tests and looking at your snippet (expecially with doSomething not being virtual): your problem is probably that have defined SomeType class with functions and eventually IntArray in Main.h.
If this is the case, your DLL refers to its own copy of these elements and not as you think to those in main ! THis explains why you don't see the expected values !
Solution:
File MainApp.h:
class SomeType{
public:
SomeType();
virtual void do_something();
};
File MyDLL.h:
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
class A {
public:
A(SomeType* data);
virtual void MemberFunc(); // access through vtable. No need to link
private:
SomeType* m_data;
};
extern "C" { // use unmangled name for easo of use of dynamic loaded DLL
MYDLL_API A* createInstance(SomeType* data);
};
File MyDLL.cpp:
#define MYDLL_EXPORTS
#include "MainApp.h"
#include "MyDLL.h"
A::A(SomeType* data) : m_data{ data } {}
void A::MemberFunc(){ m_data->do_something(); }
extern "C" {
MYDLL_API A* cdecl createInstance(SomeType* data){ return new A(data); }
}
File main.cpp:
#include <Windows.h>
#include <iostream>
#include <vector>
#include "MainApp.h"
#include "MyDLL.h"
using namespace std;
vector<int> IntArray;
SomeType::SomeType(){
IntArray.resize(1000);
IntArray[0] = 1; IntArray[1] = 101; IntArray[2] = 10101;
}
void SomeType::do_something(){
for (int i = 0; i < 4; i++) // read
cout << IntArray[i] << endl;
IntArray[3] = 2702; // write
}
int main(int ac, char**av)
{
HINSTANCE LoadMe = LoadLibrary(L"MyDLL.dll");
if(LoadMe != 0)
cout << "DLL Library successfully loaded!\n";
else throw exception("DLL library failed to load!\n");
typedef A*(*_createInstance)(SomeType*);
_createInstance fcreateInstance = (_createInstance) GetProcAddress(LoadMe, "createInstance");
if (fcreateInstance)
cout << "DLL function found !\n";
else throw exception("Function not found in DLL!\n");
SomeType someType;
A* a = fcreateInstance(&someType);
a->MemberFunc();
cin.get();
}

Using a C++ class member function (cannot be static) as a C callback function

I have a C library function that expects a function pointer for callback, and I want to pass in a C++ member function. The C++ function modifies a member variable, so I can't use a static free function (as suggested in several similar posts). My attempt (shown below) fails with a compiler error.
This post comes closest to what I need:
Using a C++ class member function as a C callback function
How can I do this without static functions? Thanks!
test.h
#ifndef TEST_H_
#define TEST_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*handler_t)(int foo, void *bar);
void set_handler(handler_t h);
#ifdef __cplusplus
}
#endif
#endif
test.c
#include "test.h"
#include <stdlib.h>
static handler_t handler_ = NULL;
void set_handler(handler_t h) {
handler_ = h;
}
void handle_event(int foo, void *bar) {
if (handler_ != NULL) handler_(foo, bar);
}
test.cpp
#include "test.h"
#include <iostream>
using namespace std;
class Foo {
public:
Foo() : ctr_(0) {};
// handler needs to access non-static variable, so it can't be static
void handler(int foo, void *bar) { ++ctr_; }
private:
int ctr_;
};
int main(int argc, char **argv) {
// error: can't convert to "void (*)(int, void*)"
set_handler(&Foo::handler);
cout << "done" << endl;
return 0;
}
GCC barf
$ gcc test.cpp test.c
test.cpp: In function ‘int main(int, char**)’:
test.cpp:18: error: cannot convert ‘void (Foo::*)(int, void*)’ to ‘void (*)(int, void*)’ for argument ‘1’ to ‘void set_handler(void (*)(int, void*))’
It is not possible, at least with that handler_t signature.
While you can create a free function on your .cpp to wrap the member call, you need a pointer to the Foo instance:
void my_wrap(int foo, void* bar) {
Foo* some_foo_instance = ...;
some_foo_instance->handler(foo, bar);
}
int main(int argc, char **argv) {
set_handler(&my_wrap);
}
You need some void* to pass the Foo instance as a handler attribute:
// Header
typedef void (*handler_t)(int foo, void *bar, void* arg1);
void set_handler(handler_t h, void* arg1);
// Impl.
void set_handler(handler_t h, void* arg1) {
handler_ = h;
handler_arg1_ = arg1;
}
// cpp
void my_wrap(int foo, void* bar, void* arg1) {
Foo* some_foo_instance = static_cast<Foo*>(arg1);
some_foo_instance->handler(foo, bar);
}
// main
int main(int argc, char **argv) {
Foo some_concrete_instance;
set_handler(&my_wrap, static_cast<void*>(&some_concrete_instance));
}
The big question is how many times you need to call set_handler multiple times to call methods on different objects. If this answer is one, you can do something like this:
#include <boost/function.hpp>
class HandlerContext
{
static boost::function<void (int, void*)> s_func
static void forward(int foo, void* bar)
{
s_func(foo, bar);
}
public:
static void set(boost::function<int, void*> const& f)
{
s_func = f;
set_handler(&HandlerContext::forward);
}
};
If the answer is "more than once", you can have multiple forwarding functions that get their function objects out of an array. You will need to preassign slots in this case, because the function in use will indicate which callback to make.
This sentence:
I have a C library function
This means you can NOT pass it any C++ object.
If the library you are using is a C library it does not know about C++ so it can not using anything that is C++ it can only use C stuff.
You MUST make it call a free function in you code.
Now your free function can then call a method on an object (that is why C callbacks have a void* parameter (so you can pass context to the callback)).
Suppose you create a mapping function:
Foo *inst = // some instance of Foo you're keeping around...
void wrapper(int foo, void *bar){
inst->handler(foo, bar);
}
Then use wrapper as the callback. Instance semantics in a callback are kind of strange, so I'm not sure how you're going to be sure you bind to the correct instance -- if this is a singleton maybe that doesn't matter.
Here is an ugly hack I invented awhile ago to solve this problem:
#include <boost/function.hpp>
#include <boost/bind.hpp>
using ::boost::function;
using ::boost::bind;
typedef int (*callback_t)(const char *, int);
typedef function<int(const char *, int)> MyFTWFunction;
template <MyFTWFunction *callback>
class callback_binder {
public:
static int callbackThunk(const char *s, int i) {
return (*callback)(s, i);
}
};
extern void register_callback(callback_t f);
int random_func(const char *s, int i)
{
if (s && *s) {
return i;
} else {
return -1;
}
}
MyFTWFunction myfunc;
class FooClass {
public:
virtual int callme(const char *s, int x) { return 0; };
};
int main(int argc, const char *argv[])
{
FooClass foo;
myfunc = bind(&FooClass::callme, &foo, _1, _2);
register_callback(&callback_binder<&myfunc>::callbackThunk);
return 0;
}
This could probably be fixed to use stuff from TR1 and remove the dependency on Boost.
And also, of course, myfunc is a global variable. It has to be a global variable. You must have one global variable per different possible object you'd want to call back into. OTOH, you can have as many of these globals as you want.
The main issue here is that it is absolutely impossible to do what you want within the given constraints. The pointer to the object you want to call back into has to come from somewhere. In some languages (like Python for example) you can create a function on-the-fly that has it's own copy of the object pointer. This cannot be done in C++. All functions must exist completely at compile time. You cannot create new function instances at run time.
With C++0x, you can sort of create functions at runtime with lambda functions. But these functions have an unspecified type and there is absolutely no way you could ever then pass them to a C function and have it work. Lambda expressions are meant to be supplied as template parameters and it's pretty hard to use them for anything else because their address can't be taken, and even if it could you ccouldn't actually know what type the pointer is pointing to.
I highly recommend not using it. The little void * most callback interfaces allow you to specify that gets handed back to you along with the data is meant to hold an object pointer of some kind. If possible, you should be doing that instead.
If you have control over how handler is defined, I recommend using Boost function objects instead of function pointers.
If you HAVE to use function pointers, define handler_t with an extra void* whose value is passed along with the handler, watch out for the gotchas Martin York linked in a comment. Then you have something like this:
typedef void (*handler_t)(int foo, void *bar, void *data);
static handler_t handler_ = NULL;
static void* handler_data_ = NULL;
void set_handler(handler_t h, void *d = NULL) {
handler_ = h;
handler_data = d;
}
void handle_event(int foo, void *bar) {
if (handler_ != NULL) handler_(foo, bar, handler_data_);
}
void foo_handler(int foo, void *bar, void *data) {
Foo *fooObj = static_cast<Foo*>(data);
fooObj->handler(foo, bar);
}
// in main
set_handler(foo_handler, &some_foo_object);