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