Lua,在葡萄牙語中的意思是「月亮」,而這裡是一套動態語言(Dynamic Language)。
或許也有人稱為腳本語言(Scripting Language),這兩者定義上還是有些許差別的,動態語言的variable無須宣告且型別可在執行期轉換,腳本語言通常用來描述物件與流程。
但lua都能扮演好這兩個角色。

通常我們可以選擇嵌入或擴展lua。
這在實作上十分容易,因為lua本身就有提供良好的介面與c溝通。
我們只需呼叫lua api即可。


-------

Part 1 - 在c中調用lua函數

首先我們須要先引進lua的標頭檔 - lua.hpp。
.hpp - 因為我用的是c++ compiler,而『lua.hpp』的內容便是,

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

extern "C"是在告訴compiler,我所引進的標頭檔使用的是c介面。
若你用的是純c的話,只需引進『lua.h』、『lualib.h』、『lauxlib.h』即可。 

接著載入lua library,我們直接在vc中手動加入lua lib。
#pragma comment( lib, "Lua/lua51.lib" )

或者把lib加入你的專案也可以,「專案->屬性->組態屬性->連結器->輸入->其他相依性」,
然後輸入你的lua lib位置。

接著就可以開始寫code了,先從c的文件檔開始吧。

#include <cstdio>
#include <cstdlib>
#include "Lua/lua.hpp"
#pragma comment( lib, "Lua/lua51.lib" )

lua_State* ls ; //lua狀態機

//調用lua函式
void Hanoi( int n, char* src, char* temp, char* dest )
{
lua_getglobal( ls, "Hanoi" ) ; //取得lua中的變量
lua_pushnumber( ls, (double)n ) ; //將第1個參數壓入lua
lua_pushstring( ls, src ) ; //將第2個參數壓入lua
lua_pushstring( ls, temp ) ; //將第3個參數壓入lua
lua_pushstring( ls, dest ) ; //將第4個參數壓入lua

lua_call( ls, 4, 0 ) ; //call lua function, 4個參數, 0個回傳數
lua_pop( ls, 0 ) ; //pop
}

int main( int argc, char** argv )
{
ls = lua_open() ;
luaopen_base( ls ) ;
luaL_openlibs( ls ) ;
luaL_dofile( ls, "hanoi.lua" ) ;

int n = 3 ;
printf( "Towers of Hanoi (with %d disks) \n", n ) ;
Hanoi( n, "A", "B", "C" ) ;

lua_close( ls ) ;
system( "PAUSE" ) ;
return 0 ;
}

還滿好理解的,先從main函式看起,
首先我們必須先要有一個lua狀態機,使用lua_open()來創建,
並使用luaopen_base( ls )載入一些io、string、math等lua自身的函式庫。
luaL_openlibs( ls )則是載入lua的輔助庫。

luaL_dofile( ls, "hanoi.lua" )把我們寫好的lua文件檔引進,供c來調用。
這裡有一個類似的函式叫,luaL_loadfile( lua_State* L, const char* filename ),
與dofile不同,loadfile只會解析語法是否錯誤,並不會幫variable配置空間也不會執行lua程式。

接著換到Hanoi函式來看看,
lua_getglobal( ls, "Hanoi" )在lua的全域變數列表中尋找Hanoi名稱,
lua_pushnumber 或 lua_pushstring都是將c的參數傳給lua中的函式,
lua_call( ls, 4, 0 )呼叫lua的函式,第二、第三個參數是說明lua的函式需要多少個參數、多少個回傳值,
lua_pop( ls, 0 )最後pop掉回傳值,這裡的函式沒有傳回值,所以第二個參數為0。

然後我們就可以安心的在c裡面使用lua的函式了!!

附上Hanoi.lua 

function Hanoi( n, src, temp, dest )
    if n == 1 then
        print( string.format( "%s -> %s", src, dest ) )
    else
        Hanoi( n-1, src, dest, temp )
        print( string.format( "%s -> %s", src, dest ) )
        Hanoi( n-1, temp, src, dest )
    end
end 

這裡我用河內塔當作lua函式的示範,並用c去呼叫它。
最後記得要在c的文件檔中close lua狀態機唷。

 

arrow
arrow
    文章標籤
    Lua C/C++ 調用函數
    全站熱搜

    鴉 發表在 痞客邦 留言(0) 人氣()