【发布时间】:2010-11-29 03:48:22
【问题描述】:
我正在尝试将表从 Lua 加载到 C++,但我无法正确处理。 我通过第一次迭代就好了,但是在第二次调用 lua_next 它崩溃了。有什么想法吗?
Lua 文件:
level = { 1, 2, 3, }
C++ 文件 - 首先我是这样做的:
lua_getglobal( L, "level" );
for( lua_pushnil( L ); lua_next( L, 1 ); lua_pop( L, -2 ) )
{
if( lua_isnumber( L, -1 ) ) {
int i = (int)lua_tonumber( L, -1 );
//use number
}
}
lua_pop( L, 1 );
然后我尝试从reference manual:
lua_getglobal( L, "level" );
int t = 1;
lua_pushnil( L );
while( lua_next( L, t ) ) {
printf( "%s - %s",
lua_typename( L, lua_type( L, -2 ) ),
lua_typename( L, lua_type( L, -1 ) ) );
lua_pop( L, 1 );
}
lua_pop( L, 1 );
最后是这个:
lua_getglobal( L, "level" );
lua_pushnil( L );
lua_next( L, 1 );
if( lua_isnumber( L, -1 ) ) {
int i = (int)lua_tonumber( L, -1 );
//use number fine
}
lua_pop( L, 1 );
lua_next( L, 1 ); //crashes
etc...
自然 L 是一个 lua_State*,我正在对其进行初始化并正常解析文件。
编辑: 为了回应 Jesse Beder 的回答,我尝试了使用记录器的代码,但仍然无法正常工作。
Log::Get().Write( "engine", "stack size: %i", lua_gettop( L ) );
lua_getglobal(L, "level");
if( lua_istable( L, -1 ) )
Log::Get().Write( "engine", "-1 is a table" );
lua_pushnil(L);
if( lua_isnil( L, -1 ) )
Log::Get().Write( "engine", "-1 is now nil" );
if( lua_istable( L, -2 ) )
Log::Get().Write( "engine", "-2 is now table" );
int pred = lua_next( L, -2 );
Log::Get().Write( "engine", "pred: %i", pred );
while( pred ) {
Log::Get().Write( "engine", "loop stuff" );
if( lua_isnumber( L, -1 ) ) {
int i = (int)lua_tonumber( L, -1 );
//use number
Log::Get().Write( "engine", "num: %i", i );
}
Log::Get().Write( "engine", "stack size: %i", lua_gettop( L ) );
if( lua_istable( L, -3 ) )
Log::Get().Write( "engine", "-3 is now table" );
lua_pop( L, 1 );
Log::Get().Write( "engine", "stack size: %i", lua_gettop( L ) );
if( lua_istable( L, -2 ) )
Log::Get().Write( "engine", "-2 is now table" );
pred = lua_next( L, -2 );
Log::Get().Write( "engine", "pred: %i", pred );
}
lua_pop( L, 1 );
它给出了这个输出:
stack size: 0
-1 is a table
-1 is now nil
-2 is now table
pred: 1
loop stuff
num: 1
stack size: 3
-3 is now table
stack size: 2
-2 is now table
杰西,你所说的一切似乎都是正确的。但仍然无法进入下一次迭代。
编辑2: 我试图将确切的代码复制到一个新项目中,跳过所有周围的类和我不想在这里和那里包含的东西。但在这里它没有,它只会在调用 lua_next 后存活下来。
编辑3: 我现在把它缩小了一点。我使用hge 作为我的 2D 引擎。 我把之前的所有代码都放在了函数测试中:
test(); //works
if( hge->System_Initiate() )
{
test(); //fails
hge->System_Start();
}
据我了解,hge 对 lua 没有任何作用。 Here 是我做的一个小测试的源代码。 hge 1.81 的来源是here。
编辑4: 问题的大小已经失控,但无济于事。这是我能够将其缩减到的最小代码。
extern "C"
{
#include <lua/lua.h>
#include <lua/lualib.h>
#include <lua/lauxlib.h>
}
#include <hge\hge.h>
bool frame_func()
{
return true;
}
bool render_func()
{
return false;
}
void test()
{
lua_State *L = lua_open();
luaL_openlibs( L );
if( luaL_dofile( L, "levels.lua" ) ) {
lua_pop( L, -1 );
return;
}
lua_getglobal(L, "level");
lua_pushnil(L);
while( lua_next( L, -2 ) ) {
if( lua_isnumber( L, -1 ) ) {
int i = (int)lua_tonumber( L, -1 );
//use number
}
lua_pop( L, 1 );
}
lua_pop( L, 1 );
lua_close( L );
}
int main()
{
HGE *hge = hgeCreate( HGE_VERSION );
hge->System_SetState( HGE_FRAMEFUNC, frame_func );
hge->System_SetState( HGE_RENDERFUNC, render_func );
hge->System_SetState( HGE_WINDOWED, true );
hge->System_SetState( HGE_SCREENWIDTH, 800 );
hge->System_SetState( HGE_SCREENHEIGHT, 600 );
hge->System_SetState( HGE_SCREENBPP, 32 );
//test(); //works
if( hge->System_Initiate() )
{
test(); //fails
hge->System_Start();
}
hge->Release();
return 0;
}
【问题讨论】:
-
所以第二次调用
lua_next崩溃了?这很奇怪......你有任何关于崩溃的调试信息(比如它到底在哪里崩溃)?此外,为了确保一切正常,您应该在每个步骤中记录密钥(它也应该是一个数字)并编辑此答案 -
我添加了lua_next的返回值。我没有任何调试信息,我也不知道如何添加它...
-
第二次编辑是一个提示 - 查看我的回答中的编辑
-
你在什么时候初始化 lua 状态?如果你把它推到
System_Initiate之后,会发生什么?你什么时候打电话给hgeCreate?我想知道他们是否都使用了一些冲突的内存池。 确实您似乎可以同时使用 lua 和 hge(谷歌“lua hge”),但初始化时可能需要做一些技巧? -
我尝试过在前后初始化 lua 状态,但没有结果。 hgeCreate 以前被称为。我不明白为什么,我之前使用过 lua,只是没有使用 lua_next。也许是我做过的其他事情搞砸了一切?但我就是看不到。