Lua 從C程式獲得Lua變數值

2021-07-09 16:51:13 字數 3026 閱讀 9273

無論你何時想要從lua 請求乙個值(比如乙個全域性變數的值),呼叫lua,被請求的值將會被壓入棧。無論你何時想要傳遞乙個值給lua,首先將這個值壓入棧,然後呼叫lua(這個值將被彈出)。

lua 以乙個嚴格的lifo 規則(後進先出;也就是說,始終訪問棧頂)來操作棧。當你呼叫lua 時,它只會改變棧頂部分。你的c**卻有更多的自由;更明確的來講,你可以查詢棧上的任何元素,甚至是在任何乙個位置插入和刪除元素。

一、壓入元素:

void lua_pushnil (lua_state *l);

void lua_pushboolean (lua_state *l, int

bool);

void lua_pushnumber (lua_state *l, double n);

void lua_pushlstring (lua_state *l, const

char *s,

size_t length);

void lua_pushstring (lua_state *l, const

char *s);

當lua 在起始以及在lua 呼叫c 的時候,棧上至少有20 個空閒的記錄(lua.h 中的lua_minstack 巨集定義了這個常量)。對於多數普通的用法棧是足夠的,所以通常我們不必去考慮它。這個函式檢測棧上是否有足夠你需要的空間:

int lua_checkstack (lua_state *l, int sz);
二、查詢元素

api 用索引來訪問棧中的元素。在棧中的第乙個元素(也就是第乙個被壓入棧的)有索引1,下乙個有索引2,以此類推。我們也可以用棧頂作為參照來訪問元素,利用負索引。在這種情況下,-1 指出棧頂元素(也就是最後被壓入的),-2 指出它的前乙個元素,以此類推。

1.型別判斷

api 提供了一套lua_is*函式來檢查乙個元素是否是乙個指定的型別,*可以是任何lua 型別。因此有lua_isnumber,lua_isstring,lua_istable 以及類似的函式。所有這些函式都有同樣的原型:

int lua_is... (lua_state *l, int

index);

2.返回元素型別

還有乙個 lua_type 函式,它返回棧中元素的型別。(lua_is*中的有些函式實際上是用了這個函式定義的巨集)在lua.h 標頭檔案中,每種型別都被定義為乙個常量:lua_tnil、lua_tboolean 、lua_tnumber 、lua_tstring 、lua_ttable 、lua_tfunction、lua_tuserdata 以及lua_tthread。這個函式主要被用在與乙個switch 語句聯合使用。當我們需要真正的檢查字串和數字型別時它也是有用的。

3.從棧中獲得值

從棧中獲得值,這裡有 lua_to*函式:

int lua_toboolean (lua_state *l, int

index);

double lua_tonumber (lua_state *l, int

index);

const char * lua_tostring (lua_state *l, int

index);

size_t lua_strlen (lua_state *l, int

index);

因為非數字返回0,5.2可以通過如下函式的isnum引數接收是否是乙個數字:

lua_number lua_tonumberx (lua_state *l, int idx, int

*isnum);

lua_integer lua_tointegerx (lua_state *l, int idx, int

*isnum);

lua_unsigned lua_tounsignedx (lua_state *l, int idx, int

*isnum);

lua_string 返回的字串結尾總會有乙個字元結束標誌0,但是字串中間也可能包含0,lua_strlen 返回字串的實際長度。

const

char *s = lua_tostring(l, -1); /* any lua string */

size_t l = lua_strlen(l, -1); /* its length */

assert(s[l] == '\0');

assert(strlen(s) <= l);

三、棧中其它操作

int lua_gettop (lua_state *l);

void lua_settop (lua_state *l, int

index);

void lua_pushvalue (lua_state *l, int

index);

void lua_remove (lua_state *l, int

index);

void lua_insert (lua_state *l, int

index);

void lua_replace (lua_state *l, int

index);

void lua_copy (lua_state *l, int fromidx, int toidx);

函式lua_gettop 返回堆疊中的元素個數,它也是棧頂元素的索引。

lua_settop 設定棧頂(也就是堆疊中的元素個數)為乙個指定的值。如果開始的棧頂高於新的棧頂,頂部的值被丟棄。否則,為了得到指定的大小這個函式壓入相應個數的空值(nil)到棧上。

函式lua_pushvalue 壓入堆疊上指定索引的乙個拷貝到棧頂;

lua_remove 移除指定索引位置的元素,並將其上面所有的元素下移來填補這個位置的空白;

lua_insert 移動棧頂元素到指定索引的位置,並將這個索引位置上面的元素全部上移至棧頂被移動留下的空

隔; lua_replace 從棧頂彈出元素值並將其設定到指定索引位置,沒有任何移動操作。

Lua學習 C 程式設定Lua全域性變數值

在c 程式中,不僅能夠獲得lua全域性變數的值,還可以重新賦予lua全域性變數新的值,同時也可以建立新的全域性變數,這些全域性變數在c 程式和lua指令碼程式中都是可以動態修改的。下面是乙個簡單的示例 test.cpp include include include extern c int mai...

lua呼叫c程式

鑑於lua5.4版本取消了lual register之後,網上教程的混亂,這裡以5.4版本為例,用lual setfuncs來代替。如下 ifdef cplusplus extern c else include include include include endif include inclu...

從lua呼叫C函式

最近在進入lua程式設計的狀態,一度令我困惑的是,lua提供的功能少的可憐,跟自備電池的python相比,可說是簡陋了。連table的列印,都需要自己實現,也因此有了一打的第三方方案。後來我想明白了,以lua和c如此緊密的關係,只需要建立lua的binding,那麼豐富而效能強大的c庫資源完全可以為...