c++ - 将成员函数指针传递给 c 风格的函数

标签 c++ c pointers c++11 callback

我正在尝试将成员函数指针传递给 c 风格的函数(因为它是 C 中的 lib)

它想要的指针定义为:

void (*)(int, const char*)

所以我要传递的函数是:

void Application::onError(int error, const char *description)

我正在尝试使用此代码传递它:

setCallback(bind(&Game::onError, this, placeholders::_1, placeholders::_2));

这给了我以下错误:

cannot convert ‘std::_Bind_helper<false, void (Application::*)(Application*, int,
const char*), Application* const, const std::_Placeholder<1>&, const 
std::_Placeholder<2>&>::type {aka std::_Bind<std::_Mem_fn<void (Application::*)
(Application*, int, const char*)>(Application*, std::_Placeholder<1>,
std::_Placeholder<2>)>}’ to ‘GLFWerrorfun {aka void (*)(int, const char*)}’ for 
argument ‘1’ to ‘void (* glfwSetErrorCallback(GLFWerrorfun))(int, const char*)’
glfwSetErrorCallback(bind(&Application::onError, this, placeholders::_1, placeholders::_2));

有没有什么方法可以成功地将成员函数作为绑定(bind)函数传递给 c 风格的函数?

最佳答案

std::bind 的结果是一个复杂的 C++ 对象。例如,它必须存储所有绑定(bind)的参数。所以它绝对不能转换为指向函数的指针。

您正在处理的回调规范显然不允许“用户数据”有效负载,因此无处隐藏指向可用于调用非静态成员函数的 C++ 对象的指针。这意味着您必须调用全局或静态成员函数,或者求助于全局/静态成员/每个线程变量来存储对象指针。

唯一 100% 可移植的方法是创建一个 C 链接函数用作回调。这样做,并使用一个全局对象指针来调用你原来的 onError():

Application *error_handling_application;

extern "C" void errorCallback(int error, const char *description)
{
  error_handling_application->onError(error, description);
}

请注意,您经常会遇到使用静态成员函数代替我的 errorCallback 的程序。这适用于大多数平台上的大多数编译器,但不能保证正常工作。 C 库需要一个具有 C 语言链接的函数。静态成员函数只能具有 C++ 语言链接。 C 函数和 C++ 函数的调用机制可能不同(取决于 ABI),这将导致对传入的静态成员函数的错误调用。

关于c++ - 将成员函数指针传递给 c 风格的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28109970/

相关文章:

c++ - 错误,动态分配对象到数组

c - C 中访问数组元素的不同方式

c - 使用函数在数组中查找最大和最小数

字符串匹配的 C 代码 [Head First C] 似乎不起作用

python - 如何通过 Boost.Python 从 python 文件导入函数

c++ - 如何使用 gdb 对 C++ 动态数组进行 "watch"处理?

c++ - 将字符串/ double vector 转换为数组

C sha1 实现不适用于 Unix

c - 打印双向链表时发生访问冲突

c++ - 这个简单的 Message 类是否证明使用智能指针是合理的?