A call to the lua function, which returns a table

I know the basics of interacting with lua and C, and I'm currently trying to execute the following lua line in C ++

Func1():Func2().Table1.value1 

I am trying to get the value "value2" and use it in my C program. Below is the code I wrote to try 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 object is an object that basically allows me to call a method that calls it the equivalent lua_ * function, and populates the lua_state pointer parameter with a member variable, which is a pointer to the lua state.

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

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

+4
source share
2 answers

You need to call Func1 before trying to get Func2 , since Func2 comes from the table returned by Func1 (and not from the global table).

Then you need to call Func2 and find Table1 in this return value, etc.

What stack leak complaint do you get? If you call this function directly from C, then yes, you must be sure that everything that you put on the lua stack (that is, not for consumption by the caller, etc.) is popped from the lua stack before you will return.

+2
source

The GetNumber function GetNumber not do the same as the lua fragment that you are going to use. In particular, GetNumber gets the value "Func2" from the registry, and your lua fragment gets the value "Func2" from the table returned by Func1() . If you are not sure that registry.Player.Func2 == Func1().Func2 always true, your C ++ version will not have the same behavior.

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

  • Get function related to _G.Func1
  • Call this function and get the table back
  • Get the function related to "Func2" from the returned table in step 2
  • Call this function and pass the table from step 2 as an argument. Get another table as the result

It was convenient for me to keep track of what the stack contains as a side comment when performing operations:

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

Note that GetNumber all the arguments that it pushes GetNumber stack before returning. This ensures that GetNumber leaves the lua stack as it was found. Perhaps this will be automated using RAII if you use C ++.

0
source

Source: https://habr.com/ru/post/1491573/


All Articles