【问题标题】:Accessing return values of Lua-functions in C++ and vice versa在 C++ 中访问 Lua 函数的返回值,反之亦然
【发布时间】:2014-12-09 23:24:37
【问题描述】:

我在 Lua 中有一些函数,在 C++ 中有一些函数,我已经设法从我的加法、幂和除法中得到正确的结果。我唯一的问题是阶乘,因为我无法将正确的数字传递给它,这应该是除法的结果。

在 Lua 中:

function powLua(a, n)
   b = 1
   for i=1,n do b = b * a end
   return b
end

function divisionLua(a, b)
   c = b/a
   return c
end

aLua = additionLua(2, 3)
bLua = additionLua(1, 3)

print("Result of additionLua is a = "..aLua.."\nResult of additionLua is b = "..bLua.."\n")

fac = factorialLua(divLua) <---- this is the part that doesn't work

print("factorial of divLua is "..fac.."\n")

在 C++ 中:

int addition(lua_State* L)
{
    int x = lua_tonumber(L, 1);
    int y = lua_tonumber(L, 2);

    lua_pushnumber(L, x + y);

    return 1;
}

int fac_calc(int x)
{
    if (x <= 1)
        return 1;

    return x * fac_calc(x-1);
}

int factorial(lua_State* L)
{   
    int fac = lua_tonumber(L, 1);

    lua_pushnumber(L, fac_calc(fac));

    return 1;
}

int power(lua_State* L, int a, int n)
{
    int b;

    lua_getglobal(L, "powLua");
    lua_pushnumber(L, a);
    lua_pushnumber(L, n);

    if (lua_pcall(L, 2, 1, 0) != 0)
        printf("error running function 'powLua': %s", lua_tostring(L, -1));

    if (!lua_isnumber(L, -1))
        printf("function `powLua' must return a number\n");
    b = lua_tonumber(L, -1);
    lua_pop(L, 1);  /* pop returned value */
    return b;
}

int division(lua_State* L, int a, int b)
{
    int c;

    lua_getglobal(L, "divisionLua");
    lua_pushnumber(L, a);
    lua_pushnumber(L, b);

    lua_pcall(L, 2, 1, 0);

    c = lua_tonumber(L, -1);
    lua_pop(L, -1);

    return c;
}

int main(int argc, char* argv[])
{
    lua_State* L = luaL_newstate();

    luaL_openlibs(L); 

    lua_pushcfunction(L, addition); 
    lua_setglobal(L, "additionLua"); 

    lua_pushcfunction(L, factorial);
    lua_setglobal(L, "factorialLua");

    luaL_dofile(L, "test01.lua");

    lua_getglobal(L, "aLua");
    int a = lua_tonumber(L, -1);
    lua_pop(L, -1);

    lua_getglobal(L, "bLua");
    int b = lua_tonumber(L, -1);
    lua_pop(L, -1);

    int pwr = power(L, a, b);

    int div = division(L, a, pwr);
    lua_pushnumber(L, div);
    lua_setglobal(L, "divLua");

    cout << "Result of a^b in powLua is pwr: " << a << "^" << b << " = " << pwr << endl;

    cout << "Result of pwr/a in divisionLua is: " << pwr << "/" << a << " = " << div << endl;

    lua_close(L);
}

我的输出是这样的:

加法Lua的结果是a = 5

加法Lua的结果是b = 4

divLua 的阶乘是 1

powLua 中 a^b 的结果是 pwr: 5^4 = 625

在 DivisionLua 中 pwr/a 的结果是:625/5 = 125

我想我必须在打开“test01.lua”文件之前将除法的结果压入堆栈,但它也不起作用。

我还通过给它一个直接值成功地测试了阶乘函数。 例如 factorialLua(5) 给我一个 120 的输出。

有人知道我的错误在哪里吗?

编辑:

在运行脚本之前设置“divLua”,测试值如下:

int div = 5;
lua_pushnumber(L, div);
lua_setglobal(L, "divLua");
...
...
luaL_dofile(L, "test01.lua");

导致factorialLua(divLua)的正确结果,但是当我将“divLua”设置为除法()的值时,如下所示:

int div = division(L, 5, 30); //div should be 6 now
lua_pushnumber(L, div);
lua_setglobal(L, "divLua");
...
...
luaL_dofile(L, "test01.lua");

factorialLua(divLua) 的结果是 1,而不是 720。

原因一定是在 luaL_dofile 之后调用了 division(),而 lua_setglobal(L, "divLua") 必须在它之前。 所以我需要让“div”知道稍后将完成的计算结果。

有什么建议吗?

【问题讨论】:

    标签: c++ lua


    【解决方案1】:

    上面有几个问题:

    • 您尝试在从 C++ 设置 divLua 之前在脚本中计算 factorialLua(divLua)
    • 您使用负索引调用 lua_pop,但它需要一个正整数。
    • 假设前两点得到解决,您将尝试计算125!,这将是一个非常很大的数字。

    请注意,您当前获得 factorialLua1 的原因是,如果给定的堆栈索引实际上不是数字,lua_tonumber 将返回 0。由于调用此函数时divLua 仍然是nil,因此您实际上是在计算factorialLua(0)

    解决此问题的两种明显方法:

    1. 在实际执行脚本之前执行lua_setglobal(L, "divLua")
    2. 将阶乘计算转移到 C++ 领域,直到实际定义了 divLua

    【讨论】:

    • (我想补充一点,可以使用luaL_checknumber 而不是lua_tonumber 来解决最后一个问题。)
    • 感谢您的快速回答。我改变了 lua_pop 调用,没有意识到这个错误。然后我在使用 luaL_dofile 执行我的脚本之前设置了 divLua 全局。我已经尝试过了,我知道你是对的,但如果我这样做,它就无法识别分区的参数,即 pwr 和 a,因为它们必须在执行脚本后设置。如果我在执行之前声明它们至少它不起作用。
    猜你喜欢
    • 2015-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-10
    • 1970-01-01
    • 1970-01-01
    • 2012-06-27
    相关资源
    最近更新 更多