Because C, I need a function pointer from a std::function I receive at runtime.
Let's call defineProxyCallback the C function taking as input a function of unsigned char.
My hack to make this work has been :
struct callBacker {
std::function<void(unsigned char)> normalKey;
};
callBacker cb = callBacker();
extern callBacker cb;
void proxy(unsigned char c) { cb.normalKey(c); };
void maincode {
// Actually cb.normalKey is taken as an input from outside
cb.normalKey = [](unsigned char c){std::cout << c << std::endl;} ;
// this was just to lake the code work
defineCallback(proxy);
}
defineCallback is defined somewhere else :
void defineCallback(void (*func)(unsigned char))
{
*func("hello world");
//should be : glutKeyboardFunc(func);
}
This works, but it's ugly AF. However, because the function pointer comes from a static function, I did not find any other way than using extern.
I've looked around but I've never found a solution for this exact problem. Any tip on making it cleaner ?
Thank you very much !
For clarity : I cannot change the fact that I need to provide a function pointer to defineCallback, nor that I receive a std::function from outside.
CodePudding user response:
I don't think this is ever going to be super-neat and tidy. If it were me I would probably use inline
functions so that they could go in a header file and I would use thread_local
storage to add a little thread safety.
Something a bit like this:
// force the compiler to make sure only one of these functions
// is linked and this can go in the header file
inline std::function<void(unsigned char)>& get_std_function()
{
// returns a different object for each thread that calls it
static thread_local std::function<void(unsigned char)> fn;
return fn;
}
inline void proxy(unsigned char c){ get_std_function()(c); };
void maincode() {
// Actually cb.normalKey is taken as an input from outside
get_std_function() = [](unsigned char c){std::cout << c << std::endl;} ;
// this was just to lake the code work
defineCallback(proxy);
}