C/C++中Lua棧的清理
Lua中一個(gè)lua_State就對(duì)應(yīng)一個(gè)lua stack,通常情況下一個(gè)lua stack就足夠了,由此便產(chǎn)生了與C/C++不同的地方:在C/C++中每個(gè)函數(shù)調(diào)用都會(huì)有自己對(duì)應(yīng)的stack,在函數(shù)調(diào)用完成之后,便將其釋放掉,因而不需要擔(dān)心stack會(huì)無限制地生長(zhǎng)下去;而在C/C++中使用Lua,由于所有的操作都基于同一個(gè)stack,因此需要程序員自己在代碼中做stack的清理工作。Lua提供了一對(duì)API來幫助程序員操縱stack:lua_gettop和lua_settop。下面給出兩種清理?xiàng)5姆椒ǎ?br> 1)為每個(gè)操作Lua棧的C/C++函數(shù)添加一個(gè)棧頂位置參數(shù)。在調(diào)用該函數(shù)時(shí)將lua_gettop的結(jié)果作為參數(shù)傳遞,在函數(shù)調(diào)用結(jié)束時(shí)使用lua_settop以傳入的棧頂位置作為參數(shù)恢復(fù)調(diào)用前的棧頂位置。CEGUI中的script module便采用此方法,下面摘錄相關(guān)代碼:

/**//*************************************************************************
Execute script code string
*************************************************************************/
void LuaScriptModule::executeString(const String& str)

{
int top = lua_gettop(d_state);
executeString_impl(str, initErrorHandlerFunc(), top);
cleanupErrorHandlerFunc();
}
void LuaScriptModule::executeString_impl(const String& str, const int err_idx,
const int top)

{
// load code into lua and call it
int error = luaL_loadbuffer(d_state, str.c_str(), str.length(), str.c_str()) ||
lua_pcall(d_state, 0, 0, err_idx);
// handle errors
if (error)
{
String errMsg = lua_tostring(d_state,-1);
lua_settop(d_state,top);
throw ScriptException("Unable to execute Lua script string: '" +
str + "'\n\n" + errMsg + "\n");
}
lua_settop(d_state,top);
}2)利用局部變量的創(chuàng)建與銷毀來自動(dòng)實(shí)現(xiàn)stack清理。下面為局部變量的類型
struct LuaStackAutoPopup
{
lua_State* mBackupLS;;
int mPos;
LuaStackAutoPopup( lua_State* vpSL )
{
mPos = lua_gettop( vpSL );
mBackupLS = vpSL;
}
void Popup( )
{
lua_settop( mBackupLS,mPos );
mBackupLS = NULL;
}
~LuaStackAutoPopup( )
{
if( mBackupLS )
lua_settop( mBackupLS,mPos );
}
};
/**//*************************************************************************
Execute script code string
*************************************************************************/
void LuaScriptModule::executeString(const String& str)

{
LuaStackAutoPopup stack(d_state);
executeString_impl(str, initErrorHandlerFunc());
cleanupErrorHandlerFunc();
}
void LuaScriptModule::executeString_impl(const String& str, const int err_idx)

{
// load code into lua and call it
int error = luaL_loadbuffer(d_state, str.c_str(), str.length(), str.c_str()) ||
lua_pcall(d_state, 0, 0, err_idx);
// handle errors
if (error)
{
String errMsg = lua_tostring(d_state,-1);
throw ScriptException("Unable to execute Lua script string: '" +
str + "'\n\n" + errMsg + "\n");
}
}posted on 2009-04-25 15:24 Heath 閱讀(5034) 評(píng)論(1) 編輯 收藏 引用 所屬分類: Script Programming


