C ++ class function pointer for function pointer

I use luabind as my lua for a C ++ shell. Luabind offers a method for using my own callback function to handle the exceptions thrown by lua, set_pcall_callback (). So I paraphrased the example from the documentation, the changes being the function logger-> log () and putting the function in a class called "Engine", so instead of a regular global function, it is now a member function, which is where my problem seems.

Here are the relevant code abbreviations:

class Engine //Whole class not shown for brevity { public: Engine(); ~Engine(); void Run(); int pcall_log(lua_State*); private: ILogger *logger; }; Engine::Run() { lua_State* L = lua_open(); luaL_openlibs(L); open(L); luabind::set_pcall_callback(&Engine::pcall_log); //<--- Problem line //etc...rest of the code not shown for brevity } int Engine::pcall_log(lua_State *L) { lua_Debug d; lua_getstack( L,1,&d); lua_getinfo( L, "Sln", &d); lua_pop(L, 1); stringstream ss; ss.clear(); ss.str(""); ss << d.short_src; ss << ": "; ss << d.currentline; ss << ": "; if ( d.name != 0) { ss << d.namewhat; ss << " "; ss << d.name; ss << ") "; } ss << lua_tostring(L, -1); logger->log(ss.str().c_str(),ELL_ERROR); return 1; } 

Here is what the compiler says at compile time:

 C:\pb\engine.cpp|31|error: cannot convert 'int (Engine::*)(lua_State*)' to 'int (*)(lua_State*)' for argument '1' to 'void luabind::set_pcall_callback(int (*)(lua_State*))'| 

So it seems that the error is that the function is expecting a regular function pointer, not a function pointer of a class member. Is there a way to cast or use an intermediate function pointer to jump to set_pcall_callback ()?

Thanks!

+4
source share
2 answers

No. A member function is not a free function. The type is completely different, and the member function pointer (PTMF) is a completely different, incompatible object from the function pointer. (For example, PTMF is usually much larger.) The most important thing is that the member-to-member pointer should always be used with the instance pointer to the object whose member you want to call, so you cannot even use PTMF the same way you use the function pointer.

The simplest solution for interacting with C code is to write a global wrapper function that sends your call, or make your member function static (in this case, it becomes almost free):

 // global! Engine * myEngine; int theCallback(lua_State * L) { return myEngine->pcall_log(L); } Engine::Run() { /* ... */ myEngine = this; luabind::set_pcall_callback(&theCallback); /* ... */ } 

The conceptual problem here is that you have an engine class, although you will have almost only one instance. For a genuine class with many objects, PTMF does not make sense, because you will need to specify which object to use for the call, while your engine class may essentially be a singleton class, which can be completely static (i.e. an illustrious namespace) .

+11
source

A static function s is usually used as a callback:

 class Engine //Whole class not shown for brevity { .... static int pcall_log(lua_State*); ... } 

This will solve your problem.

0
source

All Articles