lua lua與C C 程式的整合

2022-08-17 16:51:22 字數 3065 閱讀 2864

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學習 lua與C C 程式的整合

lua與c c 互動,主要靠lua api和向lua註冊好的函式。如下圖 注 luaglue就是讓lua指令碼中可呼叫的c 函式的介面。即那些註冊的函式。這裡起關鍵作用的要數lua state的結構,這就得講一下lua環境和lua stack。lua環境 lua環境由所有可操作的資料構成,如編譯好的...

TCL TK 與 C 程式的整合

tcl tk 與 c 程式的整合 一 簡介 比較tcl tk 提供的快速而又容易的開發圖形擁護介面,x 程式顯得很煩瑣。tcl tk 是一種指令碼語言,就象其它的一些指令碼語言一樣,也有很多事情不能夠做或很難做。解決途徑是聯合 c 與 tcl tk 一起來開發.tcl tk 系統提供c 程式呼叫tc...

WebFrom 小程式 條件查詢與分頁整合

將前面的條件查詢功能與分頁顯示整合到乙個頁面中 c autoeventwireup true codefile default.aspx.cs inherits default 展示頁 using system using system.collections using system.collec...