天天看點

lua 調用 c++

我們在上一篇學習了如何使用C++調用Lua,這一次我們處理相反的過程,使用Lua調用C++,我們使用Lua文章中一個average函數。

如何在Xcode中設定Lua環境請看:http://blog.csdn.net/honey199396/article/details/50900277

在這篇文章中我們将在C++中建立函數,告訴Lua解析器他的情況,最後從Lua調用它。後面我們也談一談lua程式的錯誤檢測。

定義函數

所有在Lua中被調用的C/C++函數都必須使用一下的定義方式:

typedef int (*lua_CFunction) (lua_State *L);
           

換句話說,函數必須要以Lua解析器作為參數并傳回一個int型變量。由于使用Lua解析器作為參數,是以函數實際上能夠從棧中取得任意數量的參數。

下面給出的C++函數average() 示範了如何接受多個參數并傳回超過一個值。該函數是一個與上面typedef相比對的函數。

  1. lua_gettop函數傳回棧頂的索引值。因為在Lua中棧是從1開始編号的,是以該函數獲得的值就是參數的個數。
  2. 在for循環中計算所有參數之和。
  3. 調用lua_pushnumber()将參數的平均值壓棧。
  4. 将參數之和壓入棧中。
  5. 最後,函數傳回2,說明有兩個傳回值在棧中。

現在函數定義好了,我們必須告訴Lua解釋器,這将在main函數中初始化Lua解釋器和載入庫後執行。

-- 注冊我們的函數
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)
{
    /* 得到參數的個數 */
    int n = lua_gettop(L);
    double sum = ;
    int i;

    /* 循環周遊參數 */
    for (i = ; i <= n; i++)
    {
        /* 所有參數求和 */
        sum += lua_tonumber(L, i);
    }

    /* 壓入平均值 */
    lua_pushnumber(L, sum / n);

    /* 壓入和 */
    lua_pushnumber(L, sum);

    /* 傳回傳回值的個數 */
    return ;
}

int main ( int argc, char *argv[] )
{
    /* 初始化Lua */
    L = luaL_newstate();

    /* 載入Lua基本庫 */
    luaL_openlibs(L);

    /* 注冊自定義函數 */
    lua_register(L, "average", average);

    /* 執行avg.lua檔案 */
    luaL_dofile(L, "avg.lua");

    /* 關閉Lua */
    lua_close(L);

    /* 暫停 */
    printf( "Press enter to exit..." );
    getchar();

    return ;
}
           

以下是調用average函數,傳入5個參數,并傳回兩個傳回值的lua檔案,我們儲存為avg.lua。

編譯

如果你的環境有什麼問題,繼續看上一篇文章。

Xcode command+r,輸出結果:

The average is  
The sum is  
Press enter to exit...
           

錯誤處理

如果你讀過LuaApi文檔,你會發現在我的average函數中沒有錯誤檢查的代碼,這樣做是為了友善說明,但是在項目中,你或許想有錯誤測試。在上面的例子中,我們至少應該檢查每個參數是不是數字。通過在for循環中添加下面的代碼來實作:

if (!lua_isnumber(L, i)) {
    lua_pushstring(L, "Incorrect argument to 'average'");
    lua_error(L);
}
           

添加這樣的檢查很容易,同時這樣也讓調試更容易。當處理用兩種不同語言編寫的程式的時候,這顯得相當重要。

本文翻譯自:http://gamedevgeek.com/tutorials/calling-c-functions-from-lua/,一部分是根據我自己的電腦環境寫的。

繼續閱讀