前言
寫過windows程式的人都知道,對於應用程式,如果需要在本地儲存一些配置資訊,我們經常將這些配置資訊寫在登錄檔或者本地的配置檔案中,很多應用都是將一些配置資訊寫在配置檔案中,比如以ini結尾的檔案,這種配置檔案很多,使用的很廣泛,然後應用程式在啟動的時候,就會解析這個配置檔案,讀取一些配置資訊。
lua的一項重要用途就是作為一種配置語言。而這篇文章將結合lua來擴充套件應用程式,這種方式提供了更大的靈活性和便利性。
這篇博文主要總結的是使用c++和lua進行互動,涉及到獲取lua中普通變數的值,lua中table的值和呼叫lua中的函式。下面就開始吧。
從乙個最簡單的例子開始
複製**
**如下:
bool cluaconfig::loadconfig()
// 載入配置檔案
int bret = lual_loadfile(l, pconfigfile);
if (bret)
// 執行配置檔案
bret = lua_pcall(l, 0, 0, 0);
if (bret)
// 讀取高
lua_getglobal(l, "width");
lua_getglobal(l, "height");
// width
if (!lua_isnumber(l, -2))
// height
if (!lua_isnumber(l, -1))
iwindowheight = lua_tointeger(l, -1);
iwindowwidth = lua_tointeger(l, -2);
return true; }
table操作
在lua中,對於table這種bug一樣存在的東西,如果c api無法操作table,那我們還能不能愉快的玩耍了。讓我們來看看c api如何操作table。現在有如下lua語句:
複製**
**如下:
background =
那麼,c api如何讀取這段**,將其中的每個欄位都解析出來呢。我先把**貼上來,然後一句一句的分析:
複製**
**如下:
// 讀取全域性的資料到棧中
lua_getglobal(l, "background");
if (!lua_istable(l, -1))
// 讀取table中字段的值,將值壓入棧中
lua_getfield(l, -1, "r");
// 讀取棧中的值
if (!lua_isnumber(l, -1))
double fvalue = lua_tonumber(l, -1);
cout << "r => " << fvalue << endl;
原諒我省略了lual_newstate這樣的**。好了,讀取乙個table,同讀取乙個全域性的變數是乙個道理的。分為以下幾步:
1.使用lua_getglobal讀取這個變數,將table讀取到棧中;
2.使用lua_getfield讀取table中字段的值,將字段的值讀取到棧中;
3.使用lua_to*系列函式,將字段的值從棧中讀取出來。
這是讀取table的操作,那設定table的操作呢?我們可以將我們自己的值寫入到棧中,這該怎麼操作?看**:
複製**
**如下:
// 將需要設定的值設定到棧中
lua_pushnumber(l, 0.55);
// 將這個值設定到table中
lua_setfield(l, -2, "r");
就是上面兩行**,當然了,你也需要先使用lua_getglobal讀取table變數,將table讀取到棧中,然後按照上面的兩行**進行設定就ok了。上面兩行**的具體含義是什麼呢?
1.lua_push*系列函式是將乙個需要設定的新值放到棧中;
2.lua_setfield函式同lua_getfield是乙個性質的函式,只不過這裡是set語義,將lua_push*到棧中的值,設定到table對應的key中。
現在讀取table,設定table都說了,那如何在表中完全建立乙個新的table呢?我們有這種需求。怎麼辦?
複製**
**如下:
// 建立乙個新的table,並壓入棧
lua_newtable(l);
// 往table中設定值
lua_pushstring(l, "
"); // 先將值壓入棧
lua_setfield(l, -2, "website"); // 將值設定到table中
// 再設定乙個值
lua_setfield(l, -2, "description");
呼叫lua函式
是的,你沒有看錯,你可以在一lua檔案中定義乙個函式,然後在c++中呼叫這個函式,貌似「高大上」的感覺。現在我就來說說這個「高大上」的功能;習慣性的上**:
複製**
**如下:
// 再來看看有引數和返回值得函式呼叫
// 現在在test.lua中定義了乙個add函式,計算兩個值的和,這兩個值就是用引數傳進去的
// 得到和以後,會返回這個和,現在我們就在c++這邊呼叫這個add函式
lua_getglobal(l, "add"); // 獲取函式,壓入棧中
lua_pushnumber(l, 10); // 壓入第乙個引數
lua_pushnumber(l, 20); // 壓入第二個引數
// 完成呼叫
iret = lua_pcall(l, 2, 1, 0);
if (iret)
// 獲得計算結果
iret = lua_isnumber(l, -1);
if (!iret)
double fvalue = lua_tonumber(l, -1);
cout << "result is " << fvalue << endl;
上面**是呼叫以下lua函式:
複製**
**如下:
-- 有引數,有返回值
function add(ia, ib)
return ia + ib
end這個簡單的lua函式沒有任何講的地方,說說上面的那一長段c++**吧。在lua中,函式和普通的值是一樣的,所以,c++呼叫lua中的函式,分為以下幾步:
使用lua_getglobal來獲取函式,然後將其壓入棧;
如果這個函式有引數的話,就需要依次將函式的引數也壓入棧;
這些準備工作都準備就緒以後,就呼叫lua_pcall開始呼叫函式了,呼叫完成以後,會將返回值壓入棧中;
最後取返回值得過程不用多說了,呼叫完畢。
總結
Lua和C語言的互動(一)
lua生來就是為了和c互動的,因此使用c擴充套件lua或者將lua嵌入到c當中都是非常流行的做法。要想理解c和lua的互動方式,首先要回顧一下c語言是如何處理函式引數的。c函式和引數 大家知道c語言是用彙編實現的,在組合語言中可沒有函式的概念,與函式對應的是叫做子過程的東西,子過程就是一段指令,乙個...
Lua和C語言的互動(一)
lua生來就是為了和c互動的,因此使用c擴充套件lua或者將lua嵌入到c當中都是非常流行的做法。要想理解c和lua的互動方式,首先要回顧一下c語言是如何處理函式引數的。c函式和引數 大家知道c語言是用彙編實現的,在組合語言中可沒有函式的概念,與函式對應的是叫做子過程的東西,子過程就是一段指令,乙個...
Lua和C語言的互動 C API
lua可作為擴充套件性語言 lua可以作為程式庫用來擴充套件應用的功能 同時也是個可擴充套件的語言 lua程式中可以註冊由其他語言實現的函式 c和lua互動的部分稱為c api。c api是乙個c 與lua進行互動的函式集。他由以下部分組成 讀寫lua全域性變數的函式 呼叫lua函式的函式 執行lu...