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狀態機唷。