Calling lua function that returns table

I know the basics of interacting with lua and C, and I am currently trying to perform the following line of lua in c++

Func1():Func2().Table1.value1

I am trying to get the value of "value2" and use it in my C program. The following is the code I wrote to attempt to get this value in 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);
}

The clientlua thing is an object that basically just allows me to call a method which calls it's lua_* function equivalent and fills the lua_state pointer parameter with a member variable that is a pointer to the lua state.

Every time I call this, it complains about me causing a lua stack leak. To solve this, I tried adding a lua_pop(3) to the end, but then it just crashes my program without reporting an error, so I assume I am doing something wrong.

Anyone have any words of wisdom for me? Kinda lost here. I doubt the above code is even written properly, how would I write the above lua call in C?


You need to call Func1 before you try to get Func2 as Func2 comes from the table that Func1 returns (and not from the global table).

Then you need to call Func2 and look up Table1 in that returned value, etc.

What "stack leak" complaint are you getting? If you are calling this function from C directly then yes, you need to be sure that anything you put on the lua stack (that isn't for consumption by the caller, etc.) is popped from the lua stack before you return.


The GetNumber function isn't doing exactly the same as the lua snippet you're going for. Specifically GetNumber is getting the value of "Func2" from the registry while your lua snippet is getting the value of "Func2" from the table returned by Func1() . Unless you're certain that registry.Player.Func2 == Func1().Func2 is always true, your C++ version will not have the same behavior.

Let's break down Func1():Func2().Table1.value1 into more explicit steps to help with the C translation:

  • Get function associated with _G.Func1
  • Call that function and get a table back
  • Get function associated with "Func2" from the returned table in step 2
  • Call that function and pass as argument the table from step 2. Get another table back as result
  • I found it helpful to track what the stack contains as a side-comment as the operations are performed:

    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;
    }
    

    Notice that GetNumber pops off all the arguments it places on the stack before returning. This ensures that GetNumber leaves the lua stack the way it was found. This can probably be automated with RAII if you're using C++.

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

    上一篇: 如何从Lua中提取C ++对象指针

    下一篇: 调用返回表的lua函数