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:
_G.Func1
"Func2"
from the returned table in step 2 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++.
上一篇: 如何从Lua中提取C ++对象指针
下一篇: 调用返回表的lua函数