将lambda作为回调传递给C函数

问题描述 投票:2回答:1

假设我有一个C函数

typedef void (* callback_t)(void* data);
status_you_dont_care_about register_callback(callback_t callback, void* data);

我想传递一个lambda作为回调。

什么是惯用的方式...

  1. 当lambda什么都没有捕获?
  2. 当lambda捕获时(按值,通过引用等)?
c++ c++11 lambda callback idiomatic
1个回答
0
投票

非捕获案例

正如评论者指出的那样,lambda隐式转换为适当类型的函数指针,因此我们可以写:

auto my_lambda = [](void* data) { /* do stuff here */};
register_callback(my_lambda, get_pointer_to_data());

这将编译。不要忘记检查返回值:-)

捕获案例

这就是我现在正在做的事情,但我怀疑它是次优的。

首先,我确保lambda捕获它需要的所有内容,以便它本身可以不带参数调用(因此它实际上不需要像回调那样使用void*)。然后我使用这段代码:

template <typename Invokable>
void callback_adapter(void *invokable_on_heap)
{
    auto retyped_callback = std::unique_ptr<Invokable>{
        reinterpret_cast<Invokable*>(invokable_on_heap)
     };
    (*retyped_callback)(std::forward<Ts>(parameters)...);
    // Note: invokable_on_heap will be delete'd
}

template <typename Invokable>
void register_invokable_as_callback(Invokable callback_) {
    Invokable* invokable_on_the_heap = new Invokable(std::move(callback_));
    register_callback(&callback_adapter<Invokable>, invokable_on_the_heap);
}

注意:使用此方法,回调只能调用一次。它可以适应需要多次调用的回调的情况,在取消注册/销毁任何回调被调用时取消分配。

© www.soinside.com 2019 - 2024. All rights reserved.