Lua_register using const char * actionname, void (* action) ()
I have a lua_State
script ready to go that will call actionname
. You need to register before running the script void(*action)()
. This process is called by a client that doesn't have access to mine lua_State
, and the client doesn't include lua. I cannot change the method signature to lua_CFunction
because the client code will not know the definitions needed to provide this functionality.
I have to provide a function like this:
void registeraction(const char * actionname, void(*action)())
{
struct functor
{
void(*action)();
functor(void(*action)()) : action(action) {}
int operator()(lua_State* state) { action(); return 0; }
};
functor callme{ action };
lua_State * L = lua->ptr;
const char * n = actionname;
lua_CFunction f{ callme }; //no suitable conversion
lua_register(L, n, f);
}
How can I wrap an action so that I can insert it into Lua?
source to share
One easy way is to give Lua a C closure.
You will need one static function that acts as a dispatcher. When you register a new action, you push the new C closure, setting the user-supplied function as the upvalue for the closure.
When Lua calls it, you will read the upvalue pointer and call that function.
#include <stdlib.h>
#include <stdio.h>
#include <lua.hpp>
typedef void(*Action)();
// user actions
void some_action()
{
printf("Must act\n");
}
void other_action()
{
printf("Hello world\n");
}
lua_State* L;
static int action_dispatcher(lua_State* L);
// this function will be exposed to users
void register_action(const char* name, Action act)
{
lua_pushlightuserdata(L, (void*)act);
lua_pushcclosure(L, &action_dispatcher, 1);
lua_setglobal(L, name);
}
int action_dispatcher(lua_State* L)
{
Action action = (Action) lua_topointer(L, lua_upvalueindex(1));
if(action) action();
return 0;
}
// test it
int main()
{
L = luaL_newstate();
// register actions
register_action("act", &some_action);
register_action("world", &other_action);
// "run" script that will call registered actions
luaL_dostring(L, "act() world()");
lua_close(L);
return EXIT_SUCCESS;
}
source to share