Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用const char*actionname,void(*action)()的lua_寄存器_C++_Lua - Fatal编程技术网

C++ 使用const char*actionname,void(*action)()的lua_寄存器

C++ 使用const char*actionname,void(*action)()的lua_寄存器,c++,lua,C++,Lua,我有一个lua\u状态可以使用脚本调用actionname。 在脚本启动之前,需要注册一个void(*action)()。此过程由一个客户端调用,该客户端无权访问我的lua\u状态,也不包括lua。我无法将方法签名更改为lua\u cffunction,因为客户端代码不知道提供该函数所需的定义 #include <stdlib.h> #include <stdio.h> #include <lua.hpp> typedef void(*Action)();

我有一个
lua\u状态
可以使用脚本调用
actionname
。 在脚本启动之前,需要注册一个
void(*action)(
)。此过程由一个客户端调用,该客户端无权访问我的
lua\u状态
,也不包括lua。我无法将方法签名更改为
lua\u cffunction
,因为客户端代码不知道提供该函数所需的定义

#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;
}
我必须在这里提供这样一个函数:

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);
}

如何包装动作以便将其放入Lua?

一个简单的方法是给Lua一个C闭包

您需要一个充当调度器的静态函数。注册新操作时,推送新的C闭包,将用户提供的函数设置为闭包的upvalue

当Lua调用它时,您将从upvalue读取指针并调用该函数

#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;
}
#包括
#包括
#包括
typedef void(*Action)();
//用户操作
使某些动作无效()
{
printf(“必须采取行动”);
}
无效其他行动()
{
printf(“Hello world\n”);
}
卢厄州*L;
静态int动作调度器(lua状态*L);
//此功能将向用户公开
无效寄存器动作(常量字符*名称,动作动作)
{
lua_pushlightuserdata(L,(无效*)法案);
lua_pushcclosure(L)和action_dispatcher(1);
lua_setglobal(L,名称);
}
int action_调度程序(lua_状态*L)
{
Action Action=(Action)lua_topointer(L,lua_upvalueindex(1));
如果(动作)动作();
返回0;
}
//测试一下
int main()
{
L=luaL_newstate();
//注册操作
登记行动(“行动”和某些行动);
登记行动(“世界”和其他行动);
//“运行”脚本,该脚本将调用已注册的操作
luaL_dostring(L,“act()world()”);
卢厄关闭(L);
返回退出成功;
}