1. ホーム
  2. スクリプト・コラム
  3. ルア

C言語によるlua関数の呼び出しを考慮する必要がある

2022-02-13 06:12:24

検討すべき問題

1. lua_pcallは、まずlua関数をスタックに置き、次に引数をスタックに置くことで、lua_pcall(luaState, 引数の数, 戻り値の数, 0)を使ってlua関数を呼び出すことができる。
イベントが発生した際にLua関数をコールバックするためには、Lua関数を保存する必要があります。luaL_ref(luaState, LUA_REGISTRYINDEX)を使用して、スタックの先頭にあるLua関数をグローバルテーブルであるLUA_REGISTRYINDEXテーブルに保存します。luaL_refはLUA_REGISTRYINDEXテーブル内のLua関数をnRefという位置で返すことになります。
3. lua_rawgeti(luaState, LUA_REGISTRYINDEX, nRef)を使用して、以前に保存したLua関数を取得します。nRefはLUA_REGISTRYINDEXテーブル内のLua関数の位置で、Lua関数はスタックの最上部に置かれ、ここで lua_pcall を使用してLua関数をコールすることが可能です。
4. luaL_unref(luaState, LUA_REGISTRYINDEX, nRef)を使用して、LUA_REGISTRYINDEXテーブルから、以前に保存したLua関数を削除します。

コピーコード コードは以下の通りです。

int LuaTest::Attach(lua_State* luaState)
{
    if(lua_isfunction(luaState, 1) ! = 1)
    {
        return 0;
    }
    lua_settop(luaState, 1);
    m_nRef = luaL_ref(luaState, LUA_REGISTRYINDEX); // save to LUA_REGISTRYINDEX table
    lua_pushinteger(luaState, nRef);
    return 1;
}

int LuaTest::Detach(lua_State* luaState)
{
    m_nRef = luaL_checknumber(luaState, 1);
    luaL_unref(luaState, LUA_REGISTRYINDEX, nRef); // remove from LUA_REGISTRYINDEX table
    m_nRef = 0;
    return 0;
}

// Event listener function
void LuaTest::EventListener(lua_State* luaState)
{
    lua_rawgeti(luaState, LUA_REGISTRYINDEX, m_nRef); // Get from the LUA_REGISTRYINDEX table
    lua_pushstring(luaState, "parameter1");
    lua_pushstring(luaState, "argument2");
    lua_pcall(luaState, 2, 1, 0); // call the lua function
    int nRet = luaL_checknumber(luaState, -1); // return value
}