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

时间:2014-03-14 12:47:40

标签: c++ function lua

我需要创建类似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函数...

你对如何做到这一点有什么想法吗?

抱歉我的英语不好。

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

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