在 C 中存储对 Lua 值的引用,如何做到这一点

Storing a reference to a Lua value in C, how can it be done?

本文关键字:引用 何做 这一点 存储 Lua      更新时间:2023-10-16

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

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

现在,我想将其扩展到Lua,以允许Lua利用并在脚本中注册键盘处理程序。

这是到目前为止的原型。

class ScriptKeyboardHandler : public KeyboardHandler
{
public:
    ... previous methods omitted
    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(...) { 
     // check if mKeyPressFunc is a function
     // call it, passing in mself, and the event args as params
} 
// On Key Release omitted because being similar to the key pressed
ScriptKeyboardHandler::createFromScript(lua_State* L)
{
    auto scriptKeyboardHandler = new ScriptKeyboardHandler(L);
    if (scriptKeyboardHandler->createCppData())
    {
        // set the light user data and return a reference to ourself (mSelf)
    }
}
ScriptKeyboardHandler::createCppData() 
{
    // get the constructor data (second param) and find the keyPressed and keyReleased function, store those for later usage
    // any other data within the constructor data will apply to object
}
-- Syntax of the lua code
MyScriptHandler = { }
MyScriptHandler.__index = MyScriptHandler
MyScriptHandler.onKeyPress = function(self, args)
end
handler = createScriptHandler(handler, MyScriptHandler)
registerKeyHandler(handler)

我只是不知道当函数作为表内的参数传入时如何找到它们。

我这样做对吗?我希望我是,这很痛苦,因为 tolua 不容易支持虚拟类,无论如何你都可以从脚本中派生。

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

以下是我对onKeyPressed的实现大致的样子。

void ScriptKeyboardHandler::onKeyPressed()
{
   //Get the table corresponding to this object from the C registry
   lua_pushlightuserdata(mpLuaState, this);
   lua_gettable(mpLuaState,LUA_REGISTRYINDEX);
   //Now get the function to call from the object
   lua_pushstring(mpLuaState,"onKeyPress");
   lua_gettable(mpLuaState,-2);
   //Now call the function 
   lua_pushvalue(mpLuaState, -2 ); // Duplicate the self table as first argument
   //TODO: Add the other arguments
   lua_pcall(mpLuaState, 1, 0, 0 ); // TODO: You'll need some error checking here and change the 1 to represent the number of args.
   lua_pop(mpLuaState,1); //Clean up the stack
}

但是,您还需要更新构造函数,以将表示处理程序的 lua 对象存储到注册表中。