我需要在 C++ 接受可调用对象的 C 接口(interface)中包装回调机制。
在 C 接口(interface)中有一个设置回调的方法:
void c_set_callback(void(*callback)(void* context), void* context);
这是我尝试用可调用的方法包装它: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 中调用可调用对象时,我会遇到段错误。请看 https://onlinegdb.com/r1WeuBz08完整的代码示例。
最佳答案
虽然 it is legal要将没有捕获的 lambda 转换为 C 风格的函数指针,您的 lambda 范围仅限于对 c_set_callback
的调用.
我的方法是调用一次 c_set_callback
在程序的最开始,使用静态 C 函数作为参数。该函数在内部调用静态 std::function<void()>
,然后让你的set_callback
只需更改静态 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);
// ...
}
关于c++ - 将通用引用转换为可调用的 void 指针,反之亦然,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62579386/