如何从Lua C API中的函数获取多个返回值?

时间:2019-06-27 07:27:35

标签: c++ c lua

我想知道如何从Lua C API中的函数获取多个返回值。

Lua代码:

function test(a, b)
  return a, b -- I would like to get these values in C++
end

C ++代码:(调用函数的部分)

/* push functions and arguments */
lua_getglobal(L, "test");  /* function to be called */
lua_pushnumber(L, 3);   /* push 1st argument */
lua_pushnumber(L, 4);   /* push 2nd argument */

/* call the function in Lua (2 arguments, 2 return) */
if (lua_pcall(L, 2, 2, 0) != 0)
{
    printf(L, "error: %s\n", lua_tostring(L, -1));
    return;
}
int ret1 = lua_tonumber(L, -1);
int ret2 = lua_tonumber(L, -1);
printf(L, "returned: %d %d\n", ret1, ret2);

我得到的结果:

  

返回:4 4

我期望的结果:

  

返回:3 4

2 个答案:

答案 0 :(得分:5)

lua_tonumber不会更改implicitly[Bird <:< { def fly(height: Int):Unit }] //implicitly[Bird <:< { val callsign: String; def fly(height: Int):Unit }] -- fails. Not sybtype. implicitly[Plane <:< { val callsign: String; def fly(height: Int):Unit }] implicitly[Bird {val callsign:String} <:< { val callsign: String; def fly(height: Int):Unit }] 的堆栈。您需要以两个不同的索引 1 读取它:

lua_State

在调用int ret1 = lua_tonumber(L, -2); int ret2 = lua_tonumber(L, -1); printf(L, "returned: %d %d\n", ret1, ret2); 之前,您的堆栈如下所示:

test

调用后 2

lua_getglobal(L, "test");  /* function to be called */
lua_pushnumber(L, 3);   /* push 1st argument */
lua_pushnumber(L, 4);   /* push 2nd argument */

|     4     |  <--- 2
+-----------+
|     3     |  <--- 1
+-----------+
|    test   |  <--- 0
+===========+

另一种方法是在阅读结果后手动弹出结果:

lua_pcall(L, 2, 2, 0) 

+-----------+
|     3     |  <--- -1
+-----------+
|     4     |  <--- -2
+===========+

1)如果一个函数返回多个结果,则第一个结果先被压入;因此,如果有int ret1 = lua_tonumber(L, -1); lua_pop(L, 1); int ret2 = lua_tonumber(L, -1); lua_pop(L, 1); printf(L, "returned: %d %d\n", ret1, ret2); 个结果,则第一个将位于索引{ {1}},最后一个索引为n 。” Programming in Lua : 25.2

2)在推入结果之前,-n从堆栈中删除函数及其参数。” Programming in Lua : 25.2

答案 1 :(得分:4)

您两次获取相同的索引:

    string s1 = "cos555cos";
    string s2 = "coscos1";
    string s3 = "22coscos";
    string s4 = "333coscos";
    string s5 = "cosco444s";


    IList<string> test = new List<string>();
    test.Add(s1);
    test.Add(s2);
    test.Add(s3);
    test.Add(s4);
    test.Add(s5);


    var orderedEnumerable = test.OrderBy(StripNumeric);

    foreach (string s in orderedEnumerable)
    {
        Console.WriteLine(s);
    }


    int StripNumeric(string input)
    {
        Regex digitsOnly = new Regex(@"[^\d]");
        return int.Parse(digitsOnly.Replace(input, ""));
    }

堆栈填充如下:

int ret1 = lua_tonumber(L, -1);
int ret2 = lua_tonumber(L, -1);

因此您的C ++代码应为:

-- Lua
return a, b

+---+
| b | <-- top ("relative" index -1)
+---+
| a | <-- -2
+---+

来自24.2.3 – Other Stack Operations

  

[...] lua_gettop函数返回堆栈中元素的数量,这也是顶部元素的索引。 请注意,负索引-x等于正索引gettop-x + 1。 [...]

此否定位置对所有与堆栈访问有关的Lua函数均有效,包括lua_tonumber。