在LUA腳本中調用C/C++函數

三、在LUA腳本中調用C/C++函數
        可以被Lua函數調用的C函數必須遵循的協議(這個協議定義了參數和結果的傳遞方式):C函數從LUA棧上按直接的順序獲取參數(第一個參數首先被push)。所以當C函數開始執行時,lua_gettop(L)返回這個C函數的參數個數。第一個參數(如果有的話)索引爲1,而最後一個參數的索引爲lua_gettop(L)。爲了將結果傳遞到LUA中,C函數將結果以直接的順序push到棧上,並以結果的個數作爲自己的返回值。棧上除結果以外的其它值將自動地被LUA以適當的方式刪除掉。與LUA函數一樣,被LUA調用的C函數也可能返回多個值到棧上。可以被Lua函數調用的C函數的類型:

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

    下面是一個Lua函數調用C函數的例子
           TestCFunc.lua的內容如下:
            function LuaCallMyCMax()

                  local tmp = MyCMax(10, 11, 12)

                     local str = "call MyCMax(10, 11, 12) in LUA and max number is "

                     print ( (str)..(tmp) )

                     return tmp

end

 

test.h的內容如下:

float max(float a, float b)

{

       return (a>b ? a : b);

}

 

float max(float a, float b, float c)

{

       float tmp = (a>b ? a : b);

       return ( tmp>c ? tmp : c);

}

 

int _cdecl MyCMax(lua_State* L)

{

       int n = lua_gettop(L);  // number of arguments

       int i;

       for (i = 1; i <= n; i++) {

              if (!lua_isnumber(L, i)) {

                     lua_pushstring(L, "incorrect argument");

                     lua_error(L);

              }

       }

 

       lua_Number tmp = 0;

 

       if (1 == n) {

              tmp = lua_tonumber(L, 1);

       } else if (2 == n)  {

              tmp = max(lua_tonumber(L, 1), lua_tonumber(L, 2));

       }

       else if (3 <= n)  {

              tmp = max(lua_tonumber(L, 1), lua_tonumber(L, 2), lua_tonumber(L, 3));

       } else {

              return 0;

       }

       lua_pushnumber(L, tmp); // first result

       return 1;               // number of results

}

test.cpp的內容如下:

// …omitted…

              lua_pushcfunction(L, MyCMax); // push  MyCMax -fuction

              lua_setglobal(L, "MyCMax");   // registry MyCMax() as a global MyCMax in LUA

                                   //或只一句lua_register(L, "MyCMax", MyCMax);

lua_getglobal(L, "LuaCallMyCMax");

              lua_pcall(L, 0, 1, 0);

              std::cout << "call LuaCallMyCMax() in C and result is "

                        << lua_tonumber(L, -1)

                        << std::endl;

              lua_pop(L,1);

// …omitted…

 

       Lua函數調用C函數的過程:
    (1)  聲明並定義一個類型爲lua_CFunction的C函數 (eg. MyCMax)

(2) 將(1)定義的C函數(指針)入棧

(3) 調用LUA庫的註冊函數(eg. lua_setglobal宏) 以某name註冊C函數
(4) 從LUA中以註冊名name(eg. MyCMax,註冊時可另取)調用C函數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章