I am trying to pass member function pointer to the c-style function (as it's lib in C)
The pointer it wants is defined as:
void (*)(int, const char*)
So the function I am trying to pass is:
void Application::onError(int error, const char *description)
I am trying to pass that with this code:
setCallback(bind(&Game::onError, this, placeholders::_1, placeholders::_2));
This gives me the following error:
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));
Is there any way to successfully pass a member function as a bound function to the c-style function?
Since the member function also has the
this
pointer as implied argument, it is not of the type accepted by the C function. Hence, IMHO the only way is to generate a standalone function with C linkageThe result of
std::bind
is a complicated C++ object. It has to store all the bound arguments, for example. So it is most definitely not convertible to a pointer to function.The callback specification you're dealing with apparently doesn't allow a "user data" payload, so there's nowhere to hide a pointer to a C++ object which you could use to invoke a non-static member funtion. This means you will have to call a global or static member function, or resort to a global/static member/per-thread variable to store the object pointer.
The only 100% portable way is to create a C linkage function to use as the callback. This does so, and uses a global object pointer to call your original
onError()
:Note that quite often, you will encounter programs which use a static member function in place of my
errorCallback
. This works with most compilers on most platforms, but it is not guaranteed to work. The C library expects a function with C language linkage. A static member function can only have C++ language linkage. It is possible for the calling mechanism of a C function and a C++ function to differ (depends on ABI), which would result in a malformed call to the static member function passed in.Not directly, no. A C++ member function needs an implicit
this
pointer, which of course C has no idea about and won't pass.The usual way around this is to introduce a "trampoline" as a class method, but perhaps there are prettier ways in more modern C++ variants.