前言#
初步了解過(guò)lua的人都知道尔当,lua和c交互式通過(guò)虛擬棧來(lái)實(shí)現(xiàn)的,這個(gè)棧造就了lua的神奇,那么我們今天來(lái)看看怎樣直接操作這個(gè)虛擬棧吉殃,首先我們要知道c調(diào)用lua和函數(shù)是通過(guò)和struct lua_State相關(guān)的棧來(lái)交換數(shù)據(jù)的密似,而Lua 調(diào)用C函數(shù)用的棧是臨時(shí)的焙矛,調(diào)用結(jié)束之后就被銷(xiāo)毀了。我們下面要講的是c調(diào)用lua的棧残腌,我們可以通過(guò)特定的api來(lái)改變棧內(nèi)數(shù)據(jù)村斟。
內(nèi)容#
lua_remove##
- 原型:void lua_remove (lua_State *L, int index);
- 解釋?zhuān)?從給定有效索引處移除一個(gè)元素, 把這個(gè)索引之上的所有元素移下來(lái)填補(bǔ)上這個(gè)空隙抛猫。
lua_replace##
- 原型:void lua_replace (lua_State *L, int index);
- 解釋?zhuān)喊褩m斣匾苿?dòng)到給定位置(并且把這個(gè)棧頂元素彈出)蟆盹, 不移動(dòng)任何元素(因此在那個(gè)位置處的值被覆蓋掉)。
Usage##
- 首先我們先新建一個(gè)文件闺金,文件命名為removetest.lua編寫(xiě)如下代碼:
-- 定義一個(gè)全局table
LanguagesTable =
{
"lua",
"c",
"c++",
"java",
"python",
}
-- 定義一個(gè)打印函數(shù)
function func_printarray()
for index,value in pairs(LanguagesTable) do
print("lua --> ["..index.."] = ".. value);
end
print("\n");
end
- 接下來(lái)我們來(lái)編寫(xiě)c++調(diào)用的函數(shù)的代碼如下:
lua_State *L = lua_open();
luaL_openlibs(L);
luaL_dofile(L,"removetest.lua"); // 加載執(zhí)行l(wèi)ua文件
lua_getglobal(L, "func_printarray");// 打印一下table的內(nèi)容
lua_pcall(L, 0, 0, 0); // 調(diào)用函數(shù)
lua_getglobal(L,"LanguagesTable"); // 將全局表壓入棧
// 記錄壓棧前元素個(gè)數(shù)
const int nPreStack = lua_gettop(L);
// 將數(shù)組元素入棧
for(int nIndex = 1; nIndex <= 5; ++nIndex)
{
lua_rawgeti(L, -1 * nIndex, nIndex);
}
// 替換元素逾滥,使用棧頂元素替換棧頂向下第3個(gè)元素
lua_replace(L, -3); // -->lua_replace用法
// 刪除元素,刪除棧頂元素
lua_remove(L, -1); // -->lua_remove用法
// 查詢(xún)當(dāng)前棧中元素個(gè)數(shù)
const int nCurStack = lua_gettop(L);
// 打印棧中元素
for(int nIndex = nPreStack + 1; nIndex <= nCurStack; ++nIndex)
{
printf("c++ --> stack pos %d : val = %s\n", nIndex, lua_tostring(L, nIndex));
}
lua_close(L); //關(guān)閉lua環(huán)境
- 結(jié)果
結(jié)論#
- 不能用偽索引來(lái)調(diào)用lua_remove這個(gè)函數(shù)掖看, 因?yàn)閭嗡饕⒉恢赶蛘鎸?shí)的棧上的位置匣距。
- 通過(guò)結(jié)果我們來(lái)分析一下最后的打印順序,開(kāi)始時(shí)我們將左右元素壓入棧中哎壳,“l(fā)ua”在棧底毅待,“python”在棧頂,執(zhí)行l(wèi)ua_replace(L, -3)后“python”將“c++”替換归榕,然后棧頂?shù)摹皃ython”被彈出尸红,然后執(zhí)行l(wèi)ua_remove(L, -1)后棧頂?shù)摹癹ava”被彈出,結(jié)果借得到了“l(fā)ua”刹泄、“c”外里、“python”的順序。
- 讀取table的內(nèi)容時(shí)一定要確保table已經(jīng)被加載到棧中特石,我在調(diào)試的時(shí)候就有好幾次因?yàn)樽x取了錯(cuò)誤的文件盅蝗,結(jié)果沒(méi)有把正確的table加載到棧中,而導(dǎo)致了程序的崩潰姆蘸。