Lua C 通過棧交換資料

2021-09-06 03:58:08 字數 2650 閱讀 9395

lua和c程式通過乙個堆疊交換資料: struct lua_state

堆疊的序號可以從棧頂和棧底計數,從棧底計數,則棧底是1,向棧頂方向遞增。從棧頂計數,則棧頂是-1,向棧底方向遞減。一般都用從棧頂計數的方式。堆疊的預設大小是20,可以用lua_checkstack修改.用lua_gettop則可以獲得棧裡的元素數目。並不是說在棧頂有乙個整形元素。而是計算了一下棧頂元素在棧裡的正index,相當於元素數目。

lua 呼叫c函式用的堆疊是臨時的,呼叫結束之後就被銷毀了。

如何從堆疊中獲取從lua指令碼中的引數

如果知道lua指令碼中某個全域性變數的名字,可以用void lua_getglobal (lua_state *l, const char *name) 。這個函式會將name所指lua變數的值放在棧頂.

如果是在c 函式中要獲取lua呼叫函式使用的引數:

首先用lua_gettop檢查引數數量

用lua_is...類函式檢測引數的型別,做好錯誤處理

用lua_to...類函式將引數轉換為number或者string.(對lua來說,只有這兩種簡單型別)

lua_tonumber返回的是double

lua_tostring返回的是char*

用lua_remove從棧中刪除掉元素

繼續獲取下乙個元素. 因為每次都呼叫lua_remove,所以每次呼叫lua_tonumber,使用的index都將固定是-1,即棧頂。

如果lua_istable成立,那麼說明棧頂是乙個table.注意table是不能取出來的,只能把table裡的元素乙個個取出來。

首先把元素的名字壓入棧頂: lua_pushstring(l,"i");然後就可以用lua_gettable呼叫,值會放在棧頂。同時剛才壓入的元素名字被彈出。用上面的辦法,可以把這個值取出來。記得也應該lua_remove。 如果table的某乙個元素也是table,重複即可。當table的所有元素都取完了,記住這個table本身還在堆疊裡,要用lua_remove把它刪除。

如果要獲取的是乙個陣列(所謂陣列,其實就是key是從1開始的數字序列的table,並且值型別相同),用lua_next可以遍歷這個陣列:

首先lua_pushnil,壓入乙個空值,然後

while (lua_next(l, -2) != 0)

}lua_remove(l,-1);//刪除nil

如何從c返回資料給lua指令碼

用lua_push...類函式壓入資料到堆疊中,並用return n;來告訴lua返回了幾個返回值。 lua是天生支援多個返回值的,如 x,y = test()。 lua會根據n從棧裡取相應的資料。

如果要返回乙個table:

lua_newtable(l);  //建立乙個**,放在棧頂

lua_pushstring(l, "mydata");  //壓入key

lua_pushnumber(l,66);  //壓入value

lua_settable(l,-3);  //彈出key,value,並設定到table裡面去

lua_pushstring(l, "subdata");  //壓入key

lua_newtable(l);  //壓入value,也是乙個table

lua_pushstring(l, "mydata");  //壓入subtable的key

lua_pushnumber(l,53);  //value

lua_settable(l,-3);  //彈出key,value,並設定到subtable

lua_settable(l,-3);  //這時候父table的位置還是-3,彈出key,value(subtable),並設定到table裡去

lua_pushstring(l, "mydata2");  //同上

lua_pushnumber(l,77);

lua_settable(l,-3);

return 1;  //堆疊裡現在就乙個table.其他都被彈掉了。

如果要返回乙個陣列,用如下**:(注意那個關於trick的注釋,我在等官方的解釋。經過驗證,這個問題只在windows版本呼叫dll中方法的時候出現。wince正常)

lua_pushstring(l,"arri");

lua_newtable(l);

}lua_settable(l,-3);

這樣產生的陣列可以在lua中如下遍歷:

for i,v in ipairs(data.arri) do

print(v)

end或者是

for i=1,table.getn(data.arri) do

print(data.arri)

end只有陣列才能這樣,name,value構成的record不行,table.getn也只對陣列有效。

由於上述**的高度相似性,所以很容易實現自動生成這些**。比如,根據c的乙個struct定義:

typedef enum baudrate;

typedef struct flag flag;  可以自動產生如下**:

bool datatolua(flag data,lua_state *l)

luatodata也是類似的。

如果使用物件導向的方式封裝起flag來,把datatolua變成flag類的乙個方法,就更加方便了。

摘自:

Lua C 通過棧交換資料

lua和c程式通過乙個堆疊交換資料 struct lua state 堆疊的序號可以從棧頂和棧底計數,從棧底計數,則棧底是1,向棧頂方向遞增。從棧頂計數,則棧頂是 1,向棧底方向遞減。一般都用從棧頂計數的方式。堆疊的預設大小是20,可以用lua checkstack修改.用lua gettop則可以...

通過交換檔案來新增Linux交換分割槽

系統型別 redhat enterprise linux5 登入使用者 root 原有交換分割槽 1g 現在要通過新增交換檔案的形式擴大系統的交換分割槽,為系統新增1g的交換分割槽。1.首先可以通過free m命令來檢視原有的swap分割槽的大小total為1019m。root rhel5serve...

單鏈表進行排序 通過節點交換,不通過值交換

原來我一直都不會對鍊錶進行排序,呵呵,比較菜。今天下了很大的功夫學習對鍊錶的排序,和大家分享一下!對鍊錶的排序主要有兩種方法 一 只交換節點中的元素,不改變鍊錶的順序。二 直接交換節點,不改變節點中的元素。其中交換節點是最麻煩的,稍不注意就會出錯!而交換節點中的元素還是比較簡單的。用幾個swap 就...