前言
寫過Windows程序的人都知道,對于應用程序,如果需要在本地保存一些配置信息,我們經常將這些配置信息寫在注冊表或者本地的配置文件中,很多應用都是將一些配置信息寫在配置文件中,比如以ini結尾的文件,這種配置文件很多,使用的很廣泛,然后應用程序在啟動的時候,就會解析這個配置文件,讀取一些配置信息。
Lua的一項重要用途就是作為一種配置語言。而這篇文章將結合Lua來擴展應用程序,這種方式提供了更大的靈活性和便利性。
這篇博文主要總結的是使用C++和Lua進行交互,涉及到獲取Lua中普通變量的值,Lua中table的值和調用Lua中的函數。下面就開始吧。
從一個最簡單的例子開始
一個GUI程序,從配置文件讀取窗口的大小,從而實現設置窗口的大小。下面我就寫一個基于MFC的窗體程序來完成這個功能。點擊這里去下載完成代碼工程。我把重點的代碼貼出來:
luaL_newstate就不說了,用爛了;luaL_loadfile用于加載一個lua文件,然后調用lua_pcall運行編譯好的程序塊,lua_pcall是在保護模式下運行Lua代碼,也就是說,出錯了,lua_pcall會返回一個錯誤代碼,并不會直接crash。當運行完程序塊后,調用了兩次lua_getglobal函數,這個函數會將全局變量值壓入棧中,所以,width的值在索引為-2的位置,height的值在索引為-1的位置;接下來,就不用多說了。就是這樣。下載程序,運行一下,就OK了,修改代碼文件夾下的config.lua文件,看看運行結果。源代碼這里下載。
table操作
在Lua中,對于table這種bug一樣存在的東西,如果C API無法操作table,那我們還能不能愉快的玩耍了。讓我們來看看C API如何操作table。現在有如下Lua語句:
那么,C API如何讀取這段代碼,將其中的每個字段都解析出來呢。我先把代碼貼上來,然后一句一句的分析:
原諒我省略了luaL_newstate這樣的代碼。好了,讀取一個table,同讀取一個全局的變量是一個道理的。分為以下幾步:
1.使用lua_getglobal讀取這個變量,將table讀取到棧中;
2.使用lua_getfield讀取table中字段的值,將字段的值讀取到棧中;
3.使用lua_to*系列函數,將字段的值從棧中讀取出來。
這是讀取table的操作,那設置table的操作呢?我們可以將我們自己的值寫入到棧中,這該怎么操作?看代碼:
就是上面兩行代碼,當然了,你也需要先使用lua_getglobal讀取table變量,將table讀取到棧中,然后按照上面的兩行代碼進行設置就OK了。上面兩行代碼的具體含義是什么呢?
1.lua_push*系列函數是將一個需要設置的新值放到棧中;
2.lua_setfield函數同lua_getfield是一個性質的函數,只不過這里是set語義,將lua_push*到棧中的值,設置到table對應的key中。
現在讀取table,設置table都說了,那如何在表中完全創建一個新的table呢?我們有這種需求。怎么辦?
我將重要的幾行代碼貼上來了,最重要的就是一個lua_newtable函數,該函數會創建一個新的table,并將這個table置于棧中,接下來就和上面設置table的值是一樣的。源代碼下載一、下載二。
調用Lua函數
是的,你沒有看錯,你可以在一lua文件中定義一個函數,然后在C++中調用這個函數,貌似“高大上”的感覺。現在我就來說說這個“高大上”的功能;習慣性的上代碼:
上面代碼是調用以下lua函數:
這個簡單的Lua函數沒有任何講的地方,說說上面的那一長段C++代碼吧。在Lua中,函數和普通的值是一樣的,所以,C++調用Lua中的函數,分為以下幾步:
使用lua_getglobal來獲取函數,然后將其壓入棧;
如果這個函數有參數的話,就需要依次將函數的參數也壓入棧;
這些準備工作都準備就緒以后,就調用lua_pcall開始調用函數了,調用完成以后,會將返回值壓入棧中;
最后取返回值得過程不用多說了,調用完畢。
源代碼這里下載。
總結
到此這篇文章總結完畢,總共花費4天的業余的零碎時間,時間主要花費在demo的編寫上,好了,這篇文章獻上,希望對大家有幫助。如果你覺的還不錯,可以將這篇文章分享給更多的朋友。當然了,你也可以掃描頁面右側的二維碼資助我寫出更好的文章了,那定是極好的。
新聞熱點
疑難解答