将成员函数指针传递给c样式函数

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

它想要的指针定义为:

void (*)(int, const char*) 

所以我试图传递的function是:

 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&, const std::_Placeholder&>::type {aka std::_Bind<std::_Mem_fn(Application*, std::_Placeholder, std::_Placeholder)>}' 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)); 

有没有办法成功将成员函数作为绑定函数传递给c风格的函数?

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

您正在处理的回调规范显然不允许“用户数据”有效负载,因此无处可隐藏指向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),这会导致对传入的静态成员函数的格式错误调用。

由于成员函数也将this指针作为隐含参数,因此它不是C函数接受的类型。 因此,恕我直言,唯一的方法是生成一个具有C链接的独立function

 class A { public: void func(int, const char*) const; }; extern "C" { void cfunc(void(*)(int, const char*)); void call_cfunc(const A*); } // in some source (non-header) file: namespace { const A*pa; void afunc(int i, const char*s) { pa->func(i,s); } } void call_cfunc(const A*a) { pa = a; cfunc(afunc); } 

不直接,没有。 C ++成员函数需要一个隐式this指针,当然C不知道也不会传递。

通常的方法是引入一个“蹦床”作为类方法,但也许在更现代的C ++变体中有更漂亮的方法。