C API 的奇怪 lua push/pop 行为
Strange lua push/pop behavior with the C API
我注意到在我的目标平台(32-bit
PowerPC
架构)上使用 C
API 在 lua
中推送和弹出值 onto/off 堆栈的行为很奇怪。考虑以下测试函数:
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_pushinteger
、lua_pushnumber
、lua_tointeger
弹出以及 lua_tonumber
分别。
确实,如果我 运行 Windows
上的代码作为 32-bit
二进制文件,它可以工作:
### 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-bit
二进制它工作。
但是,这是我的目标平台上的输出:
### 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.000000
转换为十六进制是 0x206d7580
,这也不等于 0x206D7578
的推送值。哪里不准确?)。
我很确定我没有破坏任何东西,因为我 运行 在初始化后立即进行测试 lua
:
printf("Initializing lua...\n");
lua = luaL_newstate(); /* Opens Lua */
luaL_openlibs(lua); /* Opens the standard libraries */
test_pushing_and_popping(lua);
有人知道问题出在哪里吗?
我得到的初始编译错误是这样写的:
#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
我注意到在我的目标平台(32-bit
PowerPC
架构)上使用 C
API 在 lua
中推送和弹出值 onto/off 堆栈的行为很奇怪。考虑以下测试函数:
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_pushinteger
、lua_pushnumber
、lua_tointeger
弹出以及 lua_tonumber
分别。
确实,如果我 运行 Windows
上的代码作为 32-bit
二进制文件,它可以工作:
### 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-bit
二进制它工作。
但是,这是我的目标平台上的输出:
### 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.000000
转换为十六进制是 0x206d7580
,这也不等于 0x206D7578
的推送值。哪里不准确?)。
我很确定我没有破坏任何东西,因为我 运行 在初始化后立即进行测试 lua
:
printf("Initializing lua...\n");
lua = luaL_newstate(); /* Opens Lua */
luaL_openlibs(lua); /* Opens the standard libraries */
test_pushing_and_popping(lua);
有人知道问题出在哪里吗?
我得到的初始编译错误是这样写的:
#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