将通用引用强制转换为可调用的 void 指针,反之亦然

Casting a universal reference to a callable to void pointer and vice versa

本文关键字:调用 void 指针 反之亦然 引用 转换      更新时间:2023-10-16

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

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。

尽管将没有捕获的 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);
// ...
}