如何在C语言中存储对Lua值的引用?

例如,假设我有一个键盘处理接口,在C ++中定义如下:

class KeyBoardHandler
{
public:
    virtual onKeyPressed(const KeyEventArgs& e);
    virtual onKeyReleased(const KeyEventArgs& e);
}

现在,我想将其扩展到Lua中,以便Lua可以利用并在脚本中注册KeyboardHandler。

到目前为止的原型如下。

class ScriptKeyboardHandler : public KeyboardHandler
{
public:
    ... 省略之前的方法
    static void createFromScript(lua_State* L);
    bool createCppData();

private:
    ScriptKeyBoardHandler(lua_State* L);

    int mSelf;
    int mKeyPressFunc;
    int mKeyReleaseFunc;
    lua_State* mpLuaState;
}

现在,我知道实现将类似于这样:

ScriptKeyboardHandler::ScriptKeyboardHandler(lua_State* L) :
    mpState(L)
{ }

ScriptKeyboardHandler::onKeyPressed(...) {
     // 检查是否mKeyPressFunc是函数
     // 调用它,将mself和事件参数作为参数传递进入
}

// onKeyRelease被省略,因为类似于按键按下

ScriptKeyboardHandler::createFromScript(lua_State* L)
{
    auto scriptKeyboardHandler = new ScriptKeyboardHandler(L);
    if (scriptKeyboardHandler->createCppData())
    {
        // 设置轻量级用户数据并返回对自己(mSelf)的引用
    }
}

ScriptKeyboardHandler::createCppData()
{
    // 获取构造函数数据(第二个参数)并查找keyPressed和keyReleased函数,稍后使用存储这些函数
    // 构造函数数据中的任何其他数据都将应用于对象
}

-- Lua代码的语法
MyScriptHandler = { }
MyScriptHandler.__index = MyScriptHandler

MyScriptHandler.onKeyPress = function(self, args)
end

handler = createScriptHandler(handler, MyScriptHandler)
registerKeyHandler(handler)

我只是不知道如何在表作为参数传递时找到这些函数。

我这样做对吗?我希望是,这是一个痛苦的问题,因为tolua不容易支持虚拟类,尤其是在脚本中派生的类。

我不担心其他功能,只担心如何从我的C代码中找到这些变量(按键按下函数等)。

点赞
用户221955
用户221955

下面是我实现 onKeyPressed 的大致代码。

void ScriptKeyboardHandler::onKeyPressed()
{
   // 从 C 注册表中获取对应对象的表
   lua_pushlightuserdata(mpLuaState, this);
   lua_gettable(mpLuaState,LUA_REGISTRYINDEX);

   // 从对象中获取要调用的函数
   lua_pushstring(mpLuaState,"onKeyPress");
   lua_gettable(mpLuaState,-2);

   // 调用函数
   lua_pushvalue(mpLuaState, -2 ); // 将 self 表作为第一个参数复制一份
   // 待添加其他参数
   lua_pcall(mpLuaState, 1, 0, 0 ); // 参数个数改为实际需要的数量并添加错误检查

   lua_pop(mpLuaState,1); // 清理栈

}

但你还需要更新构造函数以将代表该处理程序的 Lua 对象存储到注册表中。

2012-08-19 03:36:59