如何创建和调用lua函数,即在多个文件中,从c++

how to create and call lua function, that is in multiple files, from c++

本文关键字:文件 c++ 函数 何创建 创建 lua 调用      更新时间:2023-10-16

我需要创建类似onSomeEvent函数的东西,这将在每个Lua插件文件中。我有这个:

void onSomeEvent(int someParameter) {
    lua_getglobal(L, "onSomeEvent");
    lua_pushnumber(L, someParameter);
    lua_pcall(L, 1, 0, 0);
    lua_pop(L, 1);
}

,但它只适用于最后一个Lua文件。但是,它只调用最近加载的Lua文件中的最后一个onSomeEvent函数。我想从每个加载的Lua文件中调用onSomeEvent函数…

你有什么好主意吗?

对不起,我的英语不好。

onSomeEvent显然是全局的。每个定义它的脚本都会覆盖之前的定义。您可以为每个脚本提供自己的环境或Lua状态,但是让脚本告诉它们的事件处理程序在哪里,而不是按照约定强制它在特定的位置(例如作为一个名为onSomeEvent的全局),这会更简洁。

您的C程序只需要公开一个函数,脚本可以使用它来注册事件处理程序。下面是一个示例(注意缺少错误处理或边界检查,这只是为了说明目的):

#include "lua.h"
#include "lauxlib.h"
// list of registered handlers
static int handlers[20];
// number that are current registered
int numHandlers = 0;
// allow scripts to register a new handler
static int addEventHandler (lua_State* L) {
    if (!lua_isfunction(L,1)) {
        luaL_argerror(L, 1, "expected function");
    }
    lua_pushvalue(L, -1);
    handlers[numHandlers++] = luaL_ref(L, LUA_REGISTRYINDEX);
    return 0;
}
// call the registered handlers
static void onEvent (lua_State* L) {
    int i;
    for (i = 0; i < numHandlers; ++i) {
        lua_rawgeti(L, LUA_REGISTRYINDEX, handlers[i]);
        lua_pcall(L, 0, 0, 0);
    }
}
int main()
{    
    lua_State* L = lua_open();
    luaL_openlibs(L);
    // expose function that lets scripts register a callback handler
    lua_register(L, "addEventHandler", addEventHandler);
    // run test script
    luaL_dofile(L, "handlertest.lua");
    // call any callback(s) registered by the test script
    onEvent(L);
    lua_close(L);
    return 0;
}

handlertest.lua

addEventHandler(function() print("anonymous function called") end)
local function localFunc() print("local function called") end
addEventHandler(localFunc)
function globalFunction() print("global function called") end
addEventHandler(globalFunction)

输出
anonymous function called
local function called
global function called

如果您的脚本都定义了一个名为onSomeEvent的全局函数,那么您需要在加载脚本时为它们提供不同的环境。当需要处理事件时,运行脚本环境列表并调用每个脚本的事件处理程序。