0

I am working a with a c library inside my c++ code. Their API requires me passing a certain function pointer with a given signature. Let's say it's something like the following:

typedef int (*api_fun_t)(int);

What I want to be able to do is to pass function pointers that depend on certain parameters that are determined at runtime. Initially I thought of defining something like the following:

api_fun_t my_specialized_fun(int param){
    int fun(int x){
        // decide what to do based on param
    }
    return fun;
}

but problem c++ does not allow nested function definition. Next I figured I can achieve this via templates like the following

template <int param>
fun (int x){
    //decide what to do based on param
}

Is there any other way of doing this that does not involve global and/or static variables?

mmirzadeh
  • 6,893
  • 8
  • 36
  • 47
  • What about an array of funciton pointers? – imreal Nov 05 '12 at 07:40
  • @Nick That wont work since the parameter is only determined at runtime so I cannot list all possible functions in an array – mmirzadeh Nov 05 '12 at 07:42
  • but I cannot pass the functor to the `c` library! It only understands objects of type `api_fun_t`. I essentially could implement the nested function in a class. Problem is both parameter and the class method need to be static ... – mmirzadeh Nov 05 '12 at 07:51
  • If you cant use C++ templates aren't an option either. – imreal Nov 05 '12 at 07:53
  • I'm using `c++` and am ok with templates! I'm just wondering if there are ways of doing this. – mmirzadeh Nov 05 '12 at 07:54

2 Answers2

2

Use C++11 lambdas instead of nested functions. E.g.:

typedef int (*api_fun_t)(int);

api_fun_t my_specialized_fun(int param){
   return [](int x) {x++; return x;};
}
SomeWittyUsername
  • 18,025
  • 3
  • 42
  • 85
  • Can you show me an example of this? I'm interested to know how that would work – mmirzadeh Nov 05 '12 at 07:52
  • See here for more details: http://stackoverflow.com/questions/4726768/returning-functions – SomeWittyUsername Nov 05 '12 at 07:57
  • I don't see how that will help. The lambda can't access `param`. – ymett Nov 05 '12 at 09:45
  • @ymett no need: `if(param == val1) return lambda1; if(param == val2) return lambda2;`... Note, even if nested functions where allowed, accessing `param` from the nested function wouldn't have been possible for the same reasons as in lambda (requires state, which function pointer obviously doesn't have). – SomeWittyUsername Nov 05 '12 at 11:38
  • That's no better than an array of function pointers, which the questioner rejected in a comment to the question - "That wont work since the parameter is only determined at runtime so I cannot list all possible functions in an array". – ymett Nov 07 '12 at 14:31
  • @ymett I agree. The functions/lambdas/func templates/whatever - they all require customization according to the parameter and they will all have the required result. OP seems to be confused. Despite this, lambdas will eliminate the need for globals – SomeWittyUsername Nov 07 '12 at 15:07
0

Assuming the API allows you to pass a user parameter (as all well designed C-style callback APIs do), use a struct to hold the data, and pass a pointer to it as the parameter. You can then use the member data of the struct or call a member function as appropriate. You will have to make sure the lifetime of the struct is long enough.

If the API does not allow you to pass a user parameter, your only option is a global variable, thread local if multithreading is an issue. And write an angry email to the designer of the API.

ymett
  • 2,425
  • 14
  • 22