lua學習 lua與C C 程式的整合

2021-06-17 23:18:30 字數 2986 閱讀 4123

lua與c/c++互動,主要靠lua api和向lua註冊好的函式。如下圖

注:luaglue就是讓lua指令碼中可呼叫的c++函式的介面。即那些註冊的函式。

這裡起關鍵作用的要數lua_state的結構,這就得講一下lua環境和lua stack。

lua環境

lua環境由所有可操作的資料構成,如編譯好的函式、變數以及其他執行時記憶體。這些資料儲存在乙個稱做lua_state的結構中。所有lua應用程式都要求至少有乙個lua_state,如果需要還可以有多個(如需要為兩個不同的系統儲存不同的資料時)。

lua stack

對於我們來說,lua環境是用來傳送和接收資料的地方,它利用棧(lua stack)來達到該目的。所有的資料交換,無論是lua到c/c++語言或c/c++語言到lua都通過這個棧來完成。lua棧不同於系統棧,它只能通過lua的api函式訪問。

註冊到lua中的函式

所有註冊到lua中的函式都具有相同的原型

typedef int (*lua_function)(lua_state *l);
這個函式僅有乙個引數,即lua的狀態。它返回乙個整數,表示其壓入棧中的返回值數量。因此函式無須在壓入結果前清空棧。在它返回後,lua會自動刪除棧中結果之下的內容。

在lua使用這個函式前,必須註冊這個函式。

void lua_pushcfunction (lua_state *l, lua_cfunction f);
將乙個 c 函式壓入堆疊。 這個函式接收乙個 c 函式指標,並將乙個型別為 function 的 lua 值 壓入堆疊。當這個棧頂的值被呼叫時,將觸發對應的 c 函式。

這種方法需要重新編譯lua的執行程式,才能在lua程式中使用這個新函式。但用下面的方法會更好,直接將c函式鏈結到lua。

lua呼叫c函式時,並不依賴於函式名、包的位置或可見性規則,而只依賴於註冊時傳入的函式位址。當用c函式擴充套件lua時,最好將**設計為乙個c模組。因為現在只註冊乙個函式,但說之後可能會需要更多的函式。輔助庫為這項工作提供了乙個函式lual_register,這個函式接收一些c函式及其名稱,並將這些函式註冊到乙個與模組同名的table中。例如,假設建立乙個模組,其中包含了這個luaglue函式。首先,必須定義這個模組函式:

static int luaglue(lua_state *l)

然後,宣告乙個陣列,其中包含模組中所有函式及名稱。這個陣列元素的型別為lual_reg結構,該結構有兩個字段,乙個字串和乙個函式指標:

static const struct lual_reg mylib = ,

//結尾

};

最後,宣告乙個主函式,其中用到了lual_register:

int luaopen_mylib(lua_state *l)

其中lual_register原型為:

void lual_register (lua_state *l,const char *libname,const lual_reg *l);
lual_register根據給定的名稱(「mylib」)建立(或復用)乙個table,並用陣列mylib中的資訊填充這個table。在lual_register返回時,會將這個table留在棧中。最後,luaopen_mylib函式返回1,表示將這個table返回給lua。

ps:開啟乙個庫,當libname為null時,該函式註冊所有在lual_reg上的函式,不為null時,該函式會建立乙個table,根據libname註冊不與libname關聯的函式。

當寫完c模組後,必須將其鏈結到直譯器。如果lua直譯器支援動態鏈結的話,那麼最簡便的方法是使用動態鏈結機制。在這種情況中,必須將c**編譯成動態鏈結庫,並將這個庫放入c路徑(lua_cpath)中。然後,便可以用require從lua中載入這個模組:

require "mylib"

這名呼叫會將動態庫mylib鏈結到lua,並會尋找luaopen_mylib函式,將其註冊為乙個lua函式,然後呼叫它以開啟模組。

如果直譯器不支援動態鏈結,那麼就必須用新的模組來重新編譯lua。此外,還需要以某種方式來告訴直譯器,它應在開啟乙個新狀態的同時開啟這個模組。最簡單的做法是,將luaopen_mylib加到lual_openlibs會開啟的標準庫列表中,這個列表在檔案linit.c中。

從c++程式設計師的觀點來看,lua像乙個「黑盒子」,為一些服務處理命令和呼叫。lua通常作為最上層介面直接和程式使用者和遊戲玩家打交道,在核心程式處理之前接受並響應輸入。

如果嫌麻煩,不想手動寫這些**的話,我推薦lua_tinker。也就只有兩個檔案,lua_tinker.h,lua_tinker.cpp。

環境配置,首先你需要搭建乙個可以用lua的開發環境,這裡網上有很多,我就不多說了。然後再將lua_tinker的lua_tinker.h和lua_tinker.cpp新增到你的工程中就可以了。

lua_tinker::def(l, "cpp_func", cpp_func); //在l棧中註冊c++函式

lua_tinker::dofile(l, "sample1.lua"); //載入lua檔案

int result = lua_tinker::call(l, "lua_func", 3, 4); //呼叫lua中的function lua_func

lua_tinker::class_add(l,"classa");//在lua中註冊類

lua_tinker::class_con(l,lua_tinker::constructor);//在lua中註冊建構函式

lua_tinker::class_mem(l,"memname",&classa::memname);

ps:用lua_tinker::call是要注意,引數不支援智慧型指

Lua與C C 的互動

lua 從 取得 luatinker 可以從 取得 tolua 可以從 取得 關於lua與c c 的互動 c c 呼叫lua的函式還是比較簡單的,可以參考lua tinker的實現。lua呼叫c c 的函式如果用最原始的方式有很大限制,只能呼叫型別為 typedef int lua cfunctio...

lua與C C 的互動

基於vs的lua原始碼,位址為 lua作為小巧精悍的指令碼語言,易於嵌入c c 中 廣泛應用於遊戲ai 實際上在任何經常變化的邏輯上都可以使用lua實現,配合c c 實現的底層介面服務,能夠大大降低系統的維護成本。下面對lua和c c 的互動呼叫做乙個例項分析 lua提供了api用於在c c 中構造...

Lua與C C 互動函式問題

初學lua,遇到註冊c c 互動函式問題 在lua與c c 互動時,c c 的註冊lua函式若是乙個有返回型別 壓棧 而不是獲取型別的時候應該返回1而不是返回0,否則會出現在lua中值為nil 空 不太明白為什麼事這樣,如果有知道的大神,麻煩講解下 如 應該是 1 2 3 4 5 6 intcrea...