【发布时间】:2013-09-11 16:01:51
【问题描述】:
我必须为旧的 c 库创建一个 c++ 包装器。
在类方法中,我必须调用一个 c 函数,该函数与其他东西一起接受一个函数指针(它是一个事件处理程序,该函数接受一个在事件发生时触发的函数)。
一个简单的例子是这样的:
void myclass::add_handler(std::function<void()> handler, otherstuff...)
{
/*
* Many things.
*/
type_of_function_pointer_accepted_by_old_c_library_add_handler nameofvariable =
[handler](same_arguments_as_in_definition_of_the_old_c_function_pointer_accepted)
{
/*
* Many other things with other stuff to be done before the
* handler but always only when fired and not when myclass::add_handler is called.
*/
handler();
};
old_c_library_add_handler(nameofvariable);
/*
* Last things.
*/
}
据我所知,编译器抱怨我无法将带有捕获的 lambda 分配给旧的 c 函数指针。 问题是:我该如何解决?
【问题讨论】:
-
您不能将任何非静态成员函数传递给 c 函数指针。您必须创建一个静态函数才能将其传递给 c 函数。从该静态函数中,您必须检索要在其上调用成员函数的实例。
-
我想我没有完全理解。我应该写一个
static myclass::some_function并将其复制到c 函数指针而不是lambda。然后在静态函数内部如何检索我在 lambda 中获取的捕获变量?你能写一些示例代码吗? -
old_c_library_add_handler真正的样子是什么?设计合理的 C 库通常允许传递void*指针或类似的指针以及回调。当他们调用回调时,他们将该指针直接传回给它,以获取上下文。看看你的图书馆是不是其中之一。如果没有,那么恐怕您将不得不求助于非便携式黑客,例如动态创建机器代码 thunk。 -
是的,
old_c_library_add_handler采用 void* 参数,该参数是包含处理程序可以从调用方获取的内容的 blob。我不知道如何将std::function<void()> handler转换为void*参数,然后在处理程序中再次将其转换为std::function<void()> handler,以便我可以调用它。
标签: c c++11 lambda function-pointers wrapper