Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass a C++ lambda to a C-callback that expects a function pointer and a context?

Tags:

c++

c

c++11

lambda

I'm trying to register a callback in a C-API that uses the standard function-pointer+context paradigm. Here's what the api looks like:

void register_callback(void(*callback)(void *), void * context); 

What I'd really like to do is be able to register a C++ lambda as the callback. Additionally, I want the lambda to be one that has captured variables (ie. can't be converted to a straight stateless std::function)

What kind of adapter code would I need to write to be able to register a lambda as the callback?

like image 926
Michael Bishop Avatar asked Dec 11 '13 17:12

Michael Bishop


People also ask

Is a lambda function a callback function?

Lambda function are anonymous functions. Callback can be named or anonymous. So all lambda functions can be a callback function but not all callback function can be lambda function.

Is there lambda function in C?

Significance of Lambda Function in C/C++ Lambda Function − Lambda are functions is an inline function that doesn't require any implementation outside the scope of the main program. Lambda Functions can also be used as a value by the variable to store.

Are C++ lambdas closures?

In C++, lambda expression constructs a closure, an unnamed function object capable of capturing variables in scope.


1 Answers

The simple approach is to stick the lambda into a std::function<void()> which is kept somewhere. Potentially it is allocated on the heap and merely referenced by the void* registered with the entity taking the callback. The callback would then simply be a function like this:

extern "C" void invoke_function(void* ptr) {     (*static_cast<std::function<void()>*>(ptr))(); } 

Note that std::function<S> can hold function objects with state, e.g., lambda functions with a non-empty capture. You could register a callback like this:

register_callback(&invoke_function,   new std::function<void()>([=](){ ... })); 
like image 68
Dietmar Kühl Avatar answered Sep 30 '22 08:09

Dietmar Kühl