提问者:小点点

C API中奇怪的lua push/pop行为


我注意到,在目标平台(32位powerPC体系结构)上使用CAPI将值推入或弹出Lua中的堆栈的行为非常奇怪。 考虑以下测试函数:

void test_pushing_and_popping(lua_State *lua) {
    printf("### STARTING PUSHING/POPPING TEST ###\n");
    lua_dump_stack(lua);
    const auto value = static_cast<uint32_t>(0x206D7578);
    lua_pushinteger(lua, value);
    lua_pushnumber(lua, value);
    const auto popped_integer = lua_tointeger(lua, 1);
    const auto popped_float = lua_tonumber(lua, 2);
    printf("Popped integer: %llx\n", popped_integer);
    printf("Popped float: %f\n", popped_float);
    lua_dump_stack(lua);
    printf("Asserting equality... ");
    assert(popped_integer == popped_float);
    printf("OK!\n");
    printf("Wiping the stack...\n");
    lua_settop(lua, 0);
    lua_dump_stack(lua);
    printf("### PUSHING/POPPING TEST ENDED ###\n");
}

我希望此代码能够成功运行,并且断言将被传递,因为相同的值被推入,然后分别用LUA_PushIntegerLUA_PushNumberLUA_ToInteger以及LUA_TonNumber弹出。

实际上,如果我在Windows上以32位二进制文件的形式运行代码,它可以工作:

### STARTING PUSHING/POPPING TEST ###
Dumping the lua stack...
Stack element count: 0
Popped integer: 206d7578
Popped float: 544044408.000000
Dumping the lua stack...
Stack element count: 2
1       number  0x206D7578
2       number  0x206D7578
Asserting equality... OK!
Wiping the stack...
Dumping the lua stack...
Stack element count: 0
### PUSHING/POPPING TEST ENDED ###

同样在Linux上,它作为64位二进制文件工作。

然而,下面是我的目标平台上的输出:

### STARTING PUSHING/POPPING TEST ###
Dumping the lua stack...
Stack element count: 0
Popped integer: 8002b2bc00e3a9ac <-- Wrong!
Popped float: 544044416.000000   <-- Wrong!
Dumping the lua stack...
Stack element count: 2
1   number 0x80000000 <-- Wrong!
2   number 0x206d7580 <-- Wrong!
Asserting equality... <-- Crash (assertion fail)!

什么? 第一个值是完全错误的,甚至第二个值也是错误的。 转换为十六进制的544044416.0000000x206D7580,它也不等于0x206D7578的推送值。 不准确从何而来?)。

我很确定我没有损坏任何东西,因为我是在初始化lua之后立即运行测试的:

printf("Initializing lua...\n");
lua = luaL_newstate(); /* Opens Lua */
luaL_openlibs(lua); /* Opens the standard libraries */
test_pushing_and_popping(lua);

有谁知道问题出在哪里吗?


共1个答案

匿名用户

我得到的最初的遵从错误是这样措辞的:

#error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \
  or '-DLUA_C89_NUMBERS' (see file 'luaconf.h' for details)"

事实证明,我使用了-dlua_32bits编译标志,这导致数据类型的大小太小:

#define LUA_INTEGER int
#define LUA_NUMBER float

使用最大可能是一种方法,可以通过标记:-dlua_c89_numbers来实现。

这将数据类型定义为:

#define LUA_INTEGER long
#define LUA_NUMBER double