Home > Enterprise >  Clean way to get function pointer from external std::function
Clean way to get function pointer from external std::function

Time:05-30

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_localstorage 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);
}
  •  Tags:  
  • c
  • Related