lua與C 互動 配置檔案

2021-09-29 16:41:59 字數 3838 閱讀 2803

背景:我們可以將一些常常改動的資料寫到lua檔案中去,就不用每次在程式更改了乙個小資料的時候就要重新編譯整個專案。我們可以將這個工程裡面寫好解析指令碼的功能就可以啦~

例項:我們可以在config.lua檔案中寫到。

// config.lua檔案

width = 1000

height = 6000

然後在c++程式裡讀取指令碼檔案裡配置的資料(例如這裡是width和heigth),將資料用於c++的程式;

下述例項單純

//c++檔案的main函式部分

lua_state *lua_state;

lua_state = lual_newstate();

std::string scriptpath = "config.lua";

int status = lual_loadfile(lua_state, scriptpath.c_str()) || lua_pcall(lua_state, 0, lua_multret, 0);

if(status == lua_ok)

if(lua_isnumber(lua_state, -2))

lua_pop(lua_state, 2);

}else

lua_close(lua_state);

上述示例用到的lua_getglobal(lua_state,"width")函式,第乙個引數是棧,第二個引數是lua檔案中的全域性變數名稱;該函式將名叫「width」的全域性變數,讀取到我們的棧lua_state中。height變數的讀取也是類似。

上述乙個變數乙個變數地讀取,比較零散冗長;另一方面也不方便讀取或者設定結構性資料。例如如果需要用上述方式實現rgb顏色,就需要用三個變數colorr = 1.0, colorg = 1.0, colorb = 1.0來設定乙個顏色。lua本身的資料結構table就很好地解決了這個問題。我們可以直接設定white =

1)獲取lua的table

讀取的主要思想是先獲取表,再獲取表資料裡面的各個分量。我們依然可以用lua_getglobal來獲取white這個全域性變數,但是表裡面的資料就要我們自己去獲取了,因為表的key值和value值可以有不同的型別,不同的型別需要不同的處理和轉換api。可喜的是lua提供了乙個統一的函式lua_gettable可以處理所有的型別。它的行為模式像這樣(表中的/表示空)

開始時key入棧

lua_gettable後//

//key值(序號為-1)

/table(假設序號是-1)

table(序號為-2)

table[key]的結果(序號為-1)

//main函式主要部分**

lua_getglobal(lua_state,"white");

float red = getfield(lua_state, "r");

float green = getfield(lua_state, "g");

float blue = getfield(lua_state, "b");

std::cout << "the color is (" << red << "," << green << "," << blue<<")" << std::endl;

//getfield函式部分**

float getfield(lua_state *l, std::string key)

float res = lua_tonumber(l, -1);

lua_pop(l, 1);

return res;

}

p.s. 對於用字串來索引的情況,lua5.1提供了乙個特化版本的函式lua_getfield來簡化操作。即將原來的

lua_pushstring(l, key.c_str());

lua_gettable(l, -2)

用乙個lua_getfield(l, -1, key.c_str());來代替,-1表示table在棧頂。

2) 為lua指令碼預定義變數

1. c++裡邊預定義變數

struct color

;color mycolor[4] = ,,,

};

2. 設定表的內容(與上述getfield函式對應)

void setfield(lua_state *l, std::string key, float value)

開始時

key入棧

數值入棧

setfield後//

value值(序號為-1)

/key值(序號為-1)

/key值(序號為-2)

table(假設序號是-1)

table(假設序號是-2)

table(序號為-3)

table(序號為-1)

同理,lua5.1也為字串的key值提供了特殊的版本lua_setfield

lua_pushnumber(l, value); 

lua_setfield(l, -2, key.c_str());

3. 設定lua全域性變數

這部分是在lua裡面設定全域性變數,與前面的lua_getglobal對應。

void setcolor(lua_state *l, color c)

4. 主程式部分註冊所有預定義顏色

這部分要注意的是在執行指令碼之前註冊所有的顏色,否則lua找不到變數。

int i = 0;

while(mycolor[i].name != "null")

setcolor(lua_state, mycolor[i++]);

std::string scriptpath = "config.lua";

int status = lual_loadfile(lua_state, scriptpath.c_str()) || lua_pcall(lua_state, 0, lua_multret, 0);

if(status == lua_ok)

指令碼裡寫的是background = blue

其實還有另外一種使用c++預定義顏色的方法,而不用去lua裡邊註冊所有的預定顏色。比如我們可以讀取指令碼裡的lua_getglobal(lua_state,"background",發現它是個字串blue,然後去我們預定義的顏色裡邊找是否有名叫blue的顏色,找到了就使用相應的值。

這樣做有兩個好處:一方面是可能我們在lua裡邊用不上我們預定的那麼多顏色,註冊太多沒有必要,只帶了更大的開銷,另一方是為了便於錯誤檢查。

我們可以在lua裡邊的賦值「blue」對大小寫不敏感,在c++讀取到字串之後讓其匹配大小寫就可以了;此外,我們也可以在讀到字串但是找不到對應顏色的時候給出相應的錯誤提示。如果單純像上述那樣註冊,在lua裡邊的字串就要和預定的一模一樣,否則lua只會找不到,但是不知道**出錯了。

參考《lua程式設計第2版》

C 與Lua互動,lua環境配置

1.新建控制台專案 2.勾選空專案,靜態庫。2.標頭檔案匯入原始碼中的全部.h 標頭檔案,原始檔匯入原始碼的的.c檔案,除 lua.c 和 luac.c外 3.編譯生成lib 1.新建控制台專案,專案 屬性 c c 常規 附加包含目錄 新增lua原始檔所在的目錄 2.鏈結器 常規 附加庫目錄 新增 ...

C 嵌入Lua讀取配置檔案

這段時間一直在寫工具,遇到一些問題,google下解決了,這裡想把解決問題的成果提取出來分享下,也方便我以後使用,寫工具就應該盡量的靈活,可配置性強,配置檔案是少不了的。之前用過自定義配置檔案 我的另一篇文章中提到過 靈活是靈活,可寫起來有點麻煩,而且如果想把部分邏輯寫在外面,在配置檔案中弄個函式就...

lua做配置檔案

id col1 col2 col3 id1value1 1 value1 2 value1 3 id2value2 1 value2 2 value2 3 id3value3 1 value3 2 value3 3 以乙個m行n列的 為例 儲存結構 dictionary 第一層 key 行id,va...