詳解關(guān)于在Lua中調(diào)用C++函數(shù)
關(guān)于在Lua中調(diào)用C++函數(shù)是本文要介紹的內(nèi)容,主要是來了解在Lua中調(diào)用C++函數(shù)。由于我沒有想到一個(gè)簡(jiǎn)單的例子來說明這種情況,因此,我借用了Lua官方文檔中的average函數(shù)來進(jìn)行講解。
本教程涵蓋了Lua5.1。在Lua的每一個(gè)版本中都有一些非常不同之處。下面的示例代碼將不能在老版本的Lua下運(yùn)行。如果你仍然在使用老版本而且不愿意升級(jí),不用擔(dān)心,我已經(jīng)在文章底部提供了4.0和5.0教程的源代碼下載連接。好了,讓我們開始吧!
在本文中我們將用C++創(chuàng)建一個(gè)函數(shù),告訴Lua解釋器它的情況,***從Lua中調(diào)用它并使用其結(jié)果。本文在后面也將談一談Lua程序中的錯(cuò)誤檢查。
定義函數(shù)
***步是定義函數(shù)。所有在Lua中被調(diào)用的C/C++函數(shù)將使用下面一類指針進(jìn)行調(diào)用:
typedef int (*lua_CFunction) (lua_State *L);換句話說,函數(shù)必須要以Lua解釋器作為唯一的參數(shù),并且返回一個(gè)唯一的整數(shù)。由于用一個(gè)Lua解釋器作為參數(shù),因此函數(shù)實(shí)際上能夠從棧中取得任意數(shù)量的參數(shù)。在后面我們將看到,返回的整數(shù)實(shí)際上是被壓入棧的值的個(gè)數(shù)。通過如此容易的封裝,就能滿足你在Lua中調(diào)用C++函數(shù)的需求。
下面給出的C++函數(shù)average()演示了如何接受多個(gè)參數(shù)且返回超過一個(gè)值。記住,該函數(shù)是一個(gè)與上面typedef相匹配的函數(shù)。
lua_gettop函數(shù)返回棧頂?shù)乃饕?。因?yàn)樵贚ua中棧是從1開始編號(hào)的,因此該函數(shù)獲得的值就是參數(shù)的個(gè)數(shù)。
在for循環(huán)中計(jì)算所有參數(shù)之和。
調(diào)用lua_pushnumber()將參數(shù)的平均值壓棧。
將參數(shù)之和壓入棧中。
***,函數(shù)返回2,說明有兩個(gè)返回值在棧中。
現(xiàn)在C++函數(shù)已經(jīng)被定義好了,我們必須將它告訴Lua解釋器。這將在main函數(shù)中初始化Lua解釋器和載入庫完成之后完成:
- /* 注冊(cè)函數(shù) */
- lua_register(L, "average", average);
保存文件為luaavg.cpp。如果你直接使用C而不是C++,將文件名改為luaavg.c,然后將extern "C"刪除。
- #include <stdio.h>
- extern "C" {
- #include "lua.h"
- #include "lualib.h"
- #include "lauxlib.h"
- }
- /* 指向Lua解釋器的指針 */
- lua_State* L;
- static int average(lua_State *L)
- {
- /* 得到參數(shù)個(gè)數(shù) */
- int n = lua_gettop(L);
- double sum = 0;
- int i;
- /* 循環(huán)求參數(shù)之和 */
- for (i = 1; i <= n; i++)
- {
- /* 求和 */
- sum += lua_tonumber(L, i);
- }
- /* 壓入平均值 */
- lua_pushnumber(L, sum / n);
- /* 壓入和 */
- lua_pushnumber(L, sum);
- /* 返回返回值的個(gè)數(shù) */
- return 2;
- }
- int main ( int argc, char *argv[] )
- {
- /* 初始化Lua */
- L = lua_open();
- /* 載入Lua基本庫 */
- luaL_openlibs(L);
- /* 注冊(cè)函數(shù) */
- lua_register(L, "average", average);
- /* 運(yùn)行腳本 */
- luaL_dofile(L, "avg.lua");
- /* 清除Lua */
- lua_close(L);
- /* 暫停 */
- printf( "Press enter to exit…" );
- getchar();
- return 0;
- }
下面是以5個(gè)參數(shù)調(diào)用average函數(shù)并且顯示兩個(gè)返回值的Lua腳本,我們將其保存為avg.lua:
- -- call a C++ function
- avg, sum = average(10, 20, 30, 40, 50)
- print("The average is ", avg)
- print("The sum is ", sum)
編譯
在Linux下,在命令行鍵入:
g++ luaavg.cpp -llua -llualib -o luaavg然后,鍵入下列命令運(yùn)行:
./luaavg如果沒有問題, 程序?qū)@示出平均值、和。
在Visual C++你將需要進(jìn)行下列步驟:
創(chuàng)建一個(gè)新的空Win32控制臺(tái)應(yīng)用工程。
將"luatest.cpp"加入你的工程。
選擇項(xiàng)目菜單中的屬性菜單。
在"連接器"的"輸入"欄目的"附加依賴項(xiàng)"中輸入"lua5.1.lib"。
確定。
此時(shí),按F7構(gòu)建程序。
如果你采用的是dll庫,請(qǐng)確保將其放在應(yīng)用程序的目錄中或者windows系統(tǒng)能夠找到它的地方。如果你采用的是靜態(tài)連接庫,則不需要。
錯(cuò)誤處理
如果你已經(jīng)閱讀了Lua的API文檔,你將看出實(shí)際上我上面的average函數(shù)沒有進(jìn)行錯(cuò)誤檢查。這樣做是為了更容易地講解,然而在真實(shí)的程序中你應(yīng)該做一些錯(cuò)誤檢測(cè)。在上面的例子中,我們至少應(yīng)該檢查每個(gè)參數(shù)是不是數(shù)字。通過在for循環(huán)中添加下面的代碼來實(shí)現(xiàn):
- if (!lua_isnumber(L, i)) {
- lua_pushstring(L, "Incorrect argument to 'average'");
- lua_error(L);
- }
添加這樣的檢查很容易,同時(shí)這樣也讓調(diào)試更容易。當(dāng)處理用兩種不同語言編寫的程序的時(shí)候,這顯得相當(dāng)重要。
小結(jié):詳解關(guān)于在Lua中調(diào)用C++函數(shù)的內(nèi)容介紹完了,希望通過本文的學(xué)習(xí)能對(duì)你 有所幫助!