如何将 C++ lambda 传递给需要函数指针和上下文的 C 回调?
我正在尝试在使用标准函数指针+上下文范例的 C-API 中注册回调.这是 api 的样子:
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);
我真正想做的是能够将 C++ lambda 注册为回调.此外,我希望 lambda 是一个已捕获变量(即不能转换为直接无状态的 std::function
)
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
)
我需要编写什么样的适配器代码才能将 lambda 注册为回调?
What kind of adapter code would I need to write to be able to register a lambda as the callback?
推荐答案
简单的方法是将 lambda 粘贴到一个 std::function
中,并保存在某处.可能它是在堆上分配的,并且仅被注册到接受回调的实体的 void*
引用.回调将只是一个像这样的函数:
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))();
}
请注意,std::function
可以保存具有状态的函数对象,例如,具有非空捕获的 lambda 函数.您可以像这样注册回调:
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()>([=](){ ... }));
相关文章