将通用引用强制转换为可调用的void指针,反之亦然 [英] Casting a universal reference to a callable to void pointer and vice versa
问题描述
我需要在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屋!