调用返回表的lua函数

我知道与lua和C交互的基础知识,我目前正在尝试在c ++中执行下面的lua行

Func1():Func2().Table1.value1

我试图获得“value2”的价值并将其用于我的C程序。 以下是我为了获得C值而写的代码。

int GetNumber()
{
    int retn = 0;
    g_clientlua.lua_getfield(LUA_REGISTRYINDEX, "Player");
    g_clientlua.lua_getfield(-1, "Func2");
    g_clientlua.lua_getfield(LUA_GLOBALSINDEX, "Func1");
    g_clientlua.lua_call(0, 1);
    g_clientlua.lua_call(1, 1);
    if (g_clientlua.lua_isnil(-1)) 
        return retn;
    g_clientlua.lua_getfield(-1, "Table1");
    if (g_clientlua.lua_isnil(-1)) 
        return retn;
    g_clientlua.lua_getfield(-1, "value1");
    if (g_clientlua.lua_isnil(-1)) 
        return retn;
    retn = (int)g_clientlua.lua_tointeger(-1);
}

clientlua的东西是一个基本上只允许我调用一个方法的对象,它调用它的lua_ *函数,并用一个指向lua状态的成员变量填充lua_state指针参数。

每次我打电话时,都会抱怨我造成卢阿烟囱泄漏。 为了解决这个问题,我尝试添加一个lua_pop(3)到最后,但是它只是在没有报告错误的情况下崩溃了我的程序,所以我认为我做错了什么。

任何人对我都有任何智慧的话语? 有点失去了。 我怀疑上面的代码甚至写得不对,我会如何在C中编写上述lua调用?


您需要在尝试获取Func2之前调用Func1 ,因为Func2来自Func1返回的表(而不是来自全局表)。

然后你需要调用Func2并在返回的值中查找Table1等。

你有什么“堆栈泄漏”投诉? 如果你直接从C中调用这个函数,那么你需要确保在你返回之前,你在lua栈上放置的任何东西(不是由调用者消费的等等)从lua栈中弹出。


GetNumber函数的功能与您要使用的lua代码片段不完全相同。 具体GetNumber越来越的价值"Func2"从注册表,而你的LUA片段越来越的价值"Func2"从返回的表Func1() 。 除非您确定registry.Player.Func2 == Func1().Func2始终为true,否则您的C ++版本将不会具有相同的行为。

让我们分解一下Func1():Func2().Table1.value1变成更明确的步骤来帮助C语言翻译:

  • 获取与_G.Func1相关的功能
  • 调用该函数并返回表格
  • 在步骤2中从返回的表中获取与"Func2"关联的函数
  • 调用该函数并将其作为参数传递给第2步中的表。返回另一个表作为结果
  • 随着操作的执行,我发现跟踪堆栈包含的内容作为旁注是非常有用的:

    int GetNumber()
    {
        // Func1()
        gclientlua.lua_getfield(LUA_GLOBALSINDEX, "Func1");     // Func1
        g_clientlua.lua_call(0, 1);                             // {}
    
        // Func2( {} )
        g_clientlua.lua_getfield(-1, "Func2");                  // {}, Func2
        g_clientlua.lua_insert(-2);                             // Func2, {}
        g_clientlua.lua_call(1, 1);                             // {}
    
        if( g_clientlua.lua_type(-1) != LUA_TTABLE )
        {
          g_clientlua.lua_pop(1);
          return 0;
        }
    
        // {}.Table1
        g_clientlua.lua_getfield(-1, "Table1");                 // {}, {}(Table1)
        if( g_clientlua.lua_type(-1) != LUA_TTABLE )
        {
          g_clientlua.lua_pop(2);
          return 0;
        }
    
        // tonumber( Table1.value1 )
        g_clientlua.lua_getfield(-1, "value1");                 // {}, {}(Table1), value1
        int retn = g_clientlua.lua_tointeger(-1);
        g_clientlua.lua_pop(3);
        return retn;
    }
    

    请注意, GetNumber在返回之前弹出放置在堆栈上的所有参数。 这可以确保GetNumber按照找到的方式离开lua堆栈。 如果您使用C ++,这可能会使用RAII实现自动化。

    链接地址: http://www.djcxy.com/p/92443.html

    上一篇: Calling lua function that returns table

    下一篇: bad argument #1 to 'pairs' (table expected, got nil)