如何使用Lua擴展C/C++應用系列3-轉自bbs.luachina.net

Calling C++ Functions from Lua
這次與第二篇文章相反,介紹如何在Lua中調用C/C++函數,首先,我們用C/C++創建一個函數並告訴Lua解釋器,然後在Lua中調用這個函數並使用函數的返回值。
定義一個C/C++函數:
要想C/C++中的函數能被Lua調用,函數定義必須這樣:
代碼:typedef int (*lua_CFunction) (lua_State *L);
也就是說,函數必須以Lua解釋器作爲參數,並且返回值爲int類型。既然Lua解釋器作爲函數的參數,那麼實際上函數可以從棧中取得任意多個參數。下面我們將看到,返回的整數值代表入棧的值的數目。如果有一個C/C++函數,你想在Lua中調用他,很容易封裝一下就可以滿足上述要求。
下面的C++的average函數例子中,可以清楚地看到Lua中調用C/C++函數是如何實現的。
1. lua_gettop()返回棧頂的下標索引,由於Lua中棧的下標從1開始,這個返回值實際上也就是函數參數的個數。
2. For循環計算各個參數總和。
3. Average的參數是通過調用lua_pushnumber()入棧的。
4. 然後參數之和被入棧。
5. 最後,函數返回值爲2,表明有兩個返回值,並且已經入棧。
函數被定義之後,我們必須告訴Lua編譯器他的存在,這在main()函數中,在Lua解釋器被初始化,類庫加載之後完成的。
將下面的代碼保存爲luaavg.cpp,如果你喜歡用C而不是C++,需要保存文件爲luatest.c並且把extern去掉。
代碼:
#include <stdio.h>

extern "C" {
    #include "lua.h"
    #include "lualib.h"
    #include "lauxlib.h"
}

/* the Lua interpreter */
lua_State* L;

static int average(lua_State *L)
{
    /* get number of arguments */
    int n = lua_gettop(L);
    double sum = 0;
    int i;

    /* loop through each argument */
    for (i = 1; i <= n; i++)
    {
        /* total the arguments */
        sum += lua_tonumber(L, i);
    }

    /* push the average */
    lua_pushnumber(L, sum / n);

    /* push the sum */
    lua_pushnumber(L, sum);

    /* return the number of results */
    return 2;
}

int main ( int argc, char *argv[] )
{
    /* initialize Lua */
    L = lua_open();

    /* load Lua base libraries */
    lua_baselibopen(L);

    /* register our function */
    lua_register(L, "average", average);

    /* run the script */
    lua_dofile(L, "avg.lua");

    /* cleanup Lua */
    lua_close(L);

    return 0;
}
一個簡單的Lua腳本,調用C/C++函數,並打印其返回值,保存爲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
如果正常的話程序應該顯示:"The sum is 25"
如果你不是Linux操作系統,使用的是Vc++編譯器,你需要:
1. 創建一個新的win32控制檯應用工程。
2. 將文件luaavg.cpp添加到你的工程中。
3. 到Project, Settings點擊Link頁。
4. 添加lua+lib.lib到Object/library modules列表中。
5. 按F7編譯程序。
運行程序以前,你需要確保lua+lib.dll文件放在windows可以找到的地方,將這個文件從C:/Program Files/Lua-5.0拷貝到Visual C++ project目錄,如果編譯沒有錯誤的話,現在可以Ctrl+F5運行程序了。
關於錯誤處理:
如果你看過Lua API文檔,你會發現在上面的average函數中並未進行參數檢查,這樣做的目的是爲了更容易解釋問題,但是在一個實際的程序中錯誤檢查是必要的。在上面的例子中我們至少應該確保每一個參數是一個整數,可以用下面代碼實現:
代碼:
if (!lua_isnumber(L, i)) {
    lua_pushstring(L, "Incorrect argument to 'average'");
    lua_error(L);
}
這樣易於以後的調試。在使用兩種語言進行開發的時候這是非常重要的一點,否則你會發現你將陷於忙於兩種語言之間進行調試。
發佈了91 篇原創文章 · 獲贊 5 · 訪問量 37萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章