将通用引用强制转换为可调用的void指针,反之亦然 [英] Casting a universal reference to a callable to void pointer and vice versa

查看:56
本文介绍了将通用引用强制转换为可调用的void指针,反之亦然的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在C ++的C接口中包装一个回调机制,以接受可调用对象.在C接口中,有一种方法可以设置回调:

I need to wrap a callback mechanism in a C interface in C++ accepting callables. In the C interface there is a method to set the callback:

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

这是我尝试用可调用的方法包装它:

Here is my attempt to wrap this with a callable:

template<typename Function>
void set_callback(Function&& function)
{
    c_set_callback
        ([](void* context)
            {
                (*reinterpret_cast<typename std::decay<Function>::type*>(context))();
            }
        , reinterpret_cast<void*>(&function)
        );
}

但是我无法弄清楚为通用引用功能"转换上下文的正确方法.通过上面的实现,当从lambda内部调用callable时,我遇到了分段错误.

But I can't figure out the right way of casting the context for the universal reference to "function". With the implementation above I get a segmentation fault when the callable is invoked from within the lambda.

有关完整的代码示例,请参见 https://onlinegdb.com/r1WeuBz08 .

Please see https://onlinegdb.com/r1WeuBz08 for the full code example.

推荐答案

尽管将没有捕获的lambda强制转换为C样式函数指针,则lambda范围仅限于对 c_set_callback 的调用.

Although it is legal to cast a lambda with no captures to a C-style function pointer, your lambda scope is limited to the call to c_set_callback.

我的方法是在程序的开头用静态C函数作为参数调用一次 c_set_callback .该函数在内部调用静态的 std :: function< void()> ,然后使您的 set_callback 仅更改静态的 std :: function< void()> .

My approach would be to call once c_set_callback at the very beginning of your program, with a static C function as argument. That function, internally, calls a static std::function<void()>, and then make your set_callback to just change the static std::function<void()>.

类似

#include <functional>

std::function<void()> local_callback;

extern "C" void callback_wrapper(void *) {
    local_callback();
}

template<typename Function>
void set_callback(Function&& function) {
    local_callback = std::forward<Function>(function);
}

int main() {
    c_set_callback(&callback_wrapper, nullptr);
    // ...
}

这篇关于将通用引用强制转换为可调用的void指针,反之亦然的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆