lua

    Lua 是一個小巧的腳本語言。是巴西里約熱內盧天主教大學(Pontifical Catholic University of Rio de Janeiro)裏的一個研究小組,由Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo所組成並於1993年開發。 其設計目的是爲了嵌入應用程序中,從而爲應用程序提供靈活的擴展和定製功能。Lua由標準C編寫而成,幾乎在全部操做系統和平臺上均可以編譯,運行。Lua並無提供強大的庫,這是由它的定位決定的。因此Lua不適合做爲開發獨立應用程序的語言。Lua 有一個同時進行的JIT項目,提供在特定平臺上的即時編譯功能。
    Lua腳本能夠很容易的被C/C++ 代碼調用,也能夠反過來調用C/C++的函數,這使得Lua在應用程序中能夠被普遍應用。不只僅做爲擴展腳本,也能夠做爲普通的配置文件,代替XML,ini等文件格式,而且更容易理解和維護。[1] Lua由標準C編寫而成,代碼簡潔優美,幾乎在全部操做系統和平臺上均可以編譯,運行。 一個完整的Lua解釋器不過200k,在目前全部腳本引擎中,Lua的速度是最快的。這一切都決定了Lua是做爲嵌入式腳本的最佳選擇。程序員

保存和運行

    運行能夠經過 Lua 的交互模式,也能夠用記事本編輯代碼保存爲 .lua 的格式,經過 lua 編譯器運行。也能夠經過第三方工具,將 lua 打包獨立運行。編程

目標

    Lua的目標是成爲一個很容易嵌入其它語言中使用的語言。大多數程序員也認爲它的確作到了這一點。
不少應用程序、遊戲使用LUA做爲本身的嵌入式腳本語言,以此來實現可配置性、可擴展性。這其中包括魔獸世界、博德之門、憤怒的小鳥、VOCALOID三、太陽神三國殺 等。windows

特性

輕量級
    輕量級Lua語言的官方版本只包括一個精簡的核心和最基本的庫。這使得Lua體積小、啓動速度快,從而適合嵌入在別的程序裏。5.0.2版的Lua的內核小於120KB,而Python的內核大約860KB,Perl的內核大約1.1MB。[2]
可擴展
    可擴展 Lua並不象其它許多"大而全"的語言那樣,包括不少功能,好比網絡通信、圖形界面等。可是Lua提供了很是易於使用的擴展接口和機制:由宿主語言(一般是C或C++)提供這些功能,Lua可使用它們,就像是原本就內置的功能同樣。
其它特性
    Lua還具備其它一些特性:同時支持面向過程(procedure-oriented)編程和函數式編程(functional programming);自動內存管理;只提供了一種通用類型的表(table),用它能夠實現數組,哈希表,集合,對象;語言內置模式匹配;閉包(closure);函數也能夠看作一個值;提供多線程(協同進程 [3] ,並不是操做系統所支持的線程)支持;經過閉包和table能夠很方便地支持面向對象編程所須要的一些關鍵機制,好比數據抽象,虛函數,繼承和重載等。數組

示例代碼

    

    是的,你猜對了:hello world
1
print"Hello,world!"
    一個比較複雜一點的例子,可是它展現了什麼是閉包:
1
2
3
4
5
6
7
function create_a_counter()
     local count=0
     return function()
     count = count + 1
     return count
     end
end
    create_a_counter()返回一個記數器,每次調用這個記數器,都會獲得一個比上次大1的值。
    注意:調用的時候,若是你的調用是這樣的的:
    print(create_a_counter())
    那麼每次輸出是同樣的結果,沒有計數的效果。
    應該這樣調用:
    c1=create_a_counter()
    print(c1()) --> 1
    print(c1()) --> 2

數據交換

介紹
    Lua和C程序經過一個棧交換數據: struct lua_State
    棧的序號能夠從棧頂和棧底計數,從棧底計數,則棧底是1,向棧頂方向遞增。從棧頂計數,則棧頂是-1,向棧底方向遞 減。通常都用從棧頂計數的方式。棧的默認大小是20,能夠用lua_checkstack修改.用lua_gettop則能夠得到棧裏的元素數目。並非 說在棧頂有一個整形元素。而是計算了一下棧頂元素在棧裏的正index,至關於元素數目。
    Lua 調用C函數用的棧是臨時的,調用結束以後就被銷燬了。
    如何從棧中獲取從Lua腳本中的參數
    若是知道Lua腳本中某個 全局變量的名字,能夠用
1
void  lua_getglobal(lua_State *L,  const  char  *name)
    這個函數會將name所指Lua變量的值放在棧頂.
    若是是在C 函數中要獲取Lua調用函數使用的參數:
    首先用lua_gettop檢查參數數量
    用lua_is 類函數檢測參數的類型,作好錯誤處理
    用lua_to 類函數將參數轉換爲number或者string。(對Lua來講,只有這兩種簡單類型)
1
2
lua_tonumber返回的是double
lua_tostring返回的是char*
    用lua_remove從棧中刪除掉元素
    繼續獲取下一個元素。 由於每次都調用lua_remove,因此每次調用lua_tonumber,使用的index都將固定是-1,即棧頂。
    若是lua_istable成立,那麼說明棧頂是一個table 注意 tabl e是不能取出來的,只能把 table 裏的元素一個個取出來。
    首先把元素的名字壓入棧頂:
1
lua_pushstring(L, "i");
    而後就能夠用lua_gettable調用,值會放在棧頂。同時剛纔壓入的元素名字被彈出。用上面的辦法,能夠把這個值取出來。記得也應該 lua_remove。 若是table的某一個元素也是table,重複便可。當table的全部元素都取完了,記住這個table自己還在棧裏,要用lua_remove把它 刪除。
    若是要獲取的是一個 數組(所謂數組,其實就是key是從1開始的數字序列的table,而且 值類型相同),用lua_next能夠遍歷這個數組:
    首先lua_pushnil,壓入一個空值,而後
1
2
3
4
5
6
7
8
9
while (lua_next(L, -2)!=0)
{
     if (lua_isnumber(L, -1)) //判斷元素類型,也多是string
     {
         arrf.add(( float )lua_tonumber(L, -1)); //獲取元素的值
         lua_remove(L, -1);
     }
}
lua_remove(L,-1); //刪除NIL
    如何從C返回數據給Lua腳本
    用 lua_push 類函數壓入數據到棧中,並用return n;來告訴Lua返回了幾個返回值。 Lua是天生支持多個返回值的,如
1
x,y = Test()
    Lua會根據n從棧裏取相應的數據。
    若是要返回一個table:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
lua_newtable(L);             //建立一個表格,放在棧頂
lua_pushstring(L, "mydata" );  //壓入key
lua_pushnumber(L,66);         //壓入value
lua_settable(L,-3);          //彈出key,value,並設置到table裏面去
lua_pushstring(L, "subdata" ); //壓入key
lua_newtable(L);             //壓入value,也是一個table
lua_pushstring(L, "mydata" );  //壓入subtable的key
lua_pushnumber(L,53);
valuelua_settable(L,-3);     //彈出key,value,並設置到subtable
lua_settable(L,-3);          //這時候父table的位置仍是-3,彈出key,value(subtable),
                             //並設置到table裏去
lua_pushstring(L, "mydata2" ); //同上
lua_pushnumber(L,77);
lua_settable(L,-3);
return1;
 
//棧裏如今就一個table其餘都被彈掉了。若是要返回一個數組,
//用以下代碼:(注意那個關於trick的註釋,我在等官方的解釋。
//通過驗證,這個問題只在windows版本調用dll中方法的時候出現。WinCE正常)
lua_pushstring(L, "arri" );
lua_newtable(L);
{
     //atrick:otherwisetheluaenginewillcrash.ThiselementisinvisibleinLuascript
     lua_pushnumber(L,-1);
     lua_rawseti(L,-2,0);
     for ( int  i=0; i<arri.size(); i++)
     {
         lua_pushnumber(L, arri);
         lua_rawseti(L, -2, i+1);
     }
}
lua_settable(L,-3);
這樣產生的 數組能夠在Lua中以下遍歷:
1
2
3
4
for  i,v ini pairs(data.arri)
do
     print(v)
end
或者是
1
2
3
4
for  i=1,table.getn(data.arri)
do
 print(data.arri)
end
    只有 數組才能這樣,name,value構成的Record不行,table.getn也只對數組有效。
    因爲上述代碼的高度類似性,因此很容易實現自動生成這些代碼。好比,根據C的一個struct定義:
1
2
3
4
5
6
7
8
9
10
typedef  enum {BR_9600,BR_4800,}BaudRate;
typedef  struct  flag
{
     int     onoff;
     int     j;
     long     l;
     double     d;
     char     *name;
     BaudRate    rate;
}flag;

  能夠自動產生以下代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
bool DataToLua(flagdata, lua_State*L)
{
     lua_newtable(L);
     lua_pushstring(L, "onoff");
     lua_pushnumber(L, double)data.onoff);
     lua_settable(L, -3);
     lua_pushstring(L, "j");
     lua_pushnumber(L, (double)data.j);
     lua_settable(L, -3);
     lua_pushstring(L, "l");
     lua_pushnumber(L, (double)data.l);
     lua_settable(L, -3);
     lua_pushstring(L, "d");
     lua_pushnumber(L, double)data.d);
     lua_settable(L, -3);
     lua_pushstring(L, "name");
     lua_pushstring(L, data.name.c_str());
     lua_settable(L, -3);
     lua_pushstring(L, "rate");
     lua_pushnumber(L, (double)(int)data.rate);
     lua_settable(L, -3);
     return true;
}
    LuaToData也是相似的。
    若是使用 面向對象的方式封裝起flag來,把DataToLua變成flag類的一個方法,就更加方便了。

在線手冊

Lua中文版在線手冊。
 

使用項目

Minecraft中的電腦模組(ComputerCraft)
    全部的爲電腦和turtle(機器人)的代碼都是基於Lua的,你能夠用它們與有(無)線路由器、打印機、磁盤驅動器、(黃金)顯示器互動。
Adobe Photoshop Lightroom
    Lightroom是Adobe公司的一款攝影后期製做軟件,最開始的版本由Shadowland代碼編寫,後期版本部分使用Lua實現,Lua代碼佔到代碼總量的63%。
金庸羣俠傳lua復刻版
    這個遊戲,遊戲迷們想必都玩過了。牛人用lua腳本從新弄了下。
魔獸世界
    他的插件用的也是lua。
仙劍奇俠傳五
    解壓遊戲到資源目錄能夠看到遊戲到腳本所有是使用Lua語言編寫的。網絡

相關文章
相關標籤/搜索