青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

woaidongmao

文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
隨筆 - 1469, 文章 - 0, 評(píng)論 - 661, 引用 - 0
數(shù)據(jù)加載中……

使用 Lua 編寫可嵌入式腳本

2006 6 12

雖然編譯性編程語(yǔ)言和腳本語(yǔ)言各自具有自己獨(dú)特的優(yōu)點(diǎn),但是如果我們使用這兩種類型的語(yǔ)言來編寫大型的應(yīng)用程序會(huì)是什么樣子呢?Lua 是一種嵌入式腳本語(yǔ)言,它非常小,速度很快,功能卻非常強(qiáng)大。在創(chuàng)建其他配置文件或資源格式(以及與之對(duì)應(yīng)的解析器)之前,請(qǐng)嘗試一下 Lua

盡管諸如 PerlPythonPHP Ruby 之類的解釋性編程語(yǔ)言日益被 Web 應(yīng)用程序廣泛地采納 —— 它們已經(jīng)長(zhǎng)期用來實(shí)現(xiàn)自動(dòng)化系統(tǒng)管理任務(wù) —— 但是諸如 CC++ 之類的編譯性編程語(yǔ)言依然是必需的。編譯性編程語(yǔ)言的性能是腳本語(yǔ)言所無法企及的(只有手工調(diào)優(yōu)的匯編程序的性能才能超過它),有些軟件 —— 包括操作系統(tǒng)和設(shè)備驅(qū)動(dòng)程序 —— 只能使用編譯代碼來高效地實(shí)現(xiàn)。實(shí)際上,當(dāng)軟件和硬件需要進(jìn)行無縫地連接操作時(shí),程序員本能地就會(huì)選擇 C 編譯器:C 非常基礎(chǔ),距離原始金屬材料非常近” —— 即可以操作硬件的很多特性 —— 并且 C 的表現(xiàn)力非常強(qiáng)大,可以提供高級(jí)編程結(jié)構(gòu),例如結(jié)構(gòu)、循環(huán)、命名變量和作用域。

然而,腳本語(yǔ)言也有自己獨(dú)特的優(yōu)點(diǎn)。例如,當(dāng)某種語(yǔ)言的解釋器被成功移植到一種平臺(tái)上以后,使用這種語(yǔ)言編寫的大量腳本就可以不加任何修改在這種新平臺(tái)上運(yùn)行 —— 它們沒有諸如系統(tǒng)特定的函數(shù)庫(kù)之類的依賴限制。(我們可以考慮一下 Microsoft? Windows? 操作系統(tǒng)上的許多 DLL 文件和 UNIX? Linux? 上的很多 libcs)。另外,腳本語(yǔ)言通常都還會(huì)提供高級(jí)編程構(gòu)造和便利的操作,程序員可以使用這些功能來提高生產(chǎn)效率和靈活性。另外,使用解釋語(yǔ)言來編程的程序員工作的速度更快,因?yàn)檫@不需要編譯和鏈接的步驟。C 及其類似語(yǔ)言中的編碼、編譯、鏈接、運(yùn)行周期縮減成了更為緊湊的編寫腳本、運(yùn)行

Lua 新特性

與其他腳本語(yǔ)言一樣,Lua 也有自己的一些特性:

  • Lua 類型。 Lua 中,值可以有類型,但是變量的類型都是動(dòng)態(tài)決定的。nil、布爾型、數(shù)字字符串 類型的工作方式與我們期望的一樣。
    • Nil 是值為 nil 的一種特殊類型,用來表示沒有值。
    • 布爾型的值可以是 true false 常量。(Nil 也可以表示 false,任何非 nil 的值都表示 true。)
    • Lua 中所有的數(shù)字都是雙精度的(不過我們可以非常簡(jiǎn)便地編寫一些代碼來實(shí)現(xiàn)其他數(shù)字類型)。
    • 字符串是定長(zhǎng)字符數(shù)組。(因此,要在一個(gè)字符串后面附加上字符,必須對(duì)其進(jìn)行拷貝。)
  • 表、函數(shù)線程 類型都是引用。每個(gè)都可以賦值給一個(gè)變量,作為參數(shù)傳遞,或作為返回值從函數(shù)中返回。例如,下面是一個(gè)存儲(chǔ)函數(shù)的例子:
-- example of an anonymous function
-- returned as a value
-- see http://www.tecgraf.puc-rio.br/~lhf/ftp/doc/hopl.pdf
function add(x)
  return function (y) return (x + y) end
end
f = add(2)
print(type(f), f(10))
function  12

 

  • Lua 線程。線程是通過調(diào)用內(nèi)嵌函數(shù) coroutine.create(f) 創(chuàng)建的一個(gè)協(xié)同例程 (co-routine),其中 f 是一個(gè) Lua 函數(shù)。線程不會(huì)在創(chuàng)建時(shí)啟動(dòng);相反,它是在創(chuàng)建之后使用 coroutine.resume(t) 啟動(dòng)的,其中 t 就是一個(gè)線程。每個(gè)協(xié)同例程都必須使用 coroutine.yield() 偶爾獲得其他協(xié)同例程的處理器。
  • 賦值語(yǔ)句。Lua 允許使用多種賦值語(yǔ)句,可以先對(duì)表達(dá)式進(jìn)行求值,然后再進(jìn)行賦值。例如,下面的語(yǔ)句:
i = 3
a = {1, 3, 5, 7, 9}
i, a[i], a[i+1], b = i+1, a[i+1], a[i]
print (i, a[3], a[4], b, I)


會(huì)生成 4 7 5 nil nil。如果變量列表的個(gè)數(shù)大于值列表的個(gè)數(shù),那么多出的變量都被賦值為 nil;因此,b 就是 nil。如果值的個(gè)數(shù)多于變量的個(gè)數(shù),那么多出的值部分就會(huì)簡(jiǎn)單地丟棄。在 Lua 中,變量名是大小寫敏感的,這可以解釋為什么 I 的值是 nil

  • 塊(Chunk)。 可以是任何 Lua 語(yǔ)句序列。塊可以保存到文件中,或者保存到 Lua 程序中的字符串中。每個(gè)塊都是作為一個(gè)匿名函數(shù)體來執(zhí)行的。因此,塊可以定義局部變量和返回值。
  • 更酷的東西。Lua 具有一個(gè)標(biāo)記-清理垃圾收集器。在 Lua 5.1 中,垃圾收集器是以增量方式工作的。Lua 具有完整的詞法閉包(這與 Scheme 類似,而與 Python 不同)。Lua 具有可靠的尾部調(diào)用語(yǔ)義(同樣,這也與 Scheme 類似,而與 Python 不同)。

Programming in Lua Lua-users wiki (鏈接請(qǐng)參見后面的 參考資料 部分)中可以找到更多 Lua 代碼的例子。

在所有的工程任務(wù)中,要在編譯性語(yǔ)言和解釋性語(yǔ)言之間作出選擇,就意味著要在這種環(huán)境中對(duì)每種語(yǔ)言的優(yōu)缺點(diǎn)、權(quán)重和折中進(jìn)行評(píng)測(cè),并接受所帶來的風(fēng)險(xiǎn)。

 

在兩個(gè)世界之間最好地進(jìn)行混合

如果您希望充分利用這兩個(gè)世界的優(yōu)點(diǎn),應(yīng)該怎樣辦呢,是選擇最好的性能還是選擇高級(jí)強(qiáng)大的抽象?更進(jìn)一步說,如果我們希望對(duì)處理器密集且依賴于系統(tǒng)的算法和函數(shù)以及與系統(tǒng)無關(guān)且很容易根據(jù)需要而進(jìn)行修改的單獨(dú)邏輯進(jìn)行優(yōu)化,那又當(dāng)如何呢?

對(duì)高性能代碼和高級(jí)編程的需要進(jìn)行平衡是 Lua(一種可嵌入式腳本語(yǔ)言)要解決的問題。在需要時(shí)我們可以使用編譯后的代碼來實(shí)現(xiàn)底層的功能,然后調(diào)用 Lua 腳本來操作復(fù)雜的數(shù)據(jù)。由于 Lua 腳本是與編譯代碼獨(dú)立的,因此我們可以單獨(dú)修改這些腳本。使用 Lua,開發(fā)周期就非常類似于編碼、編譯、運(yùn)行、編寫腳本、編寫腳本、編寫腳本 ...”

例如,Lua Web 站點(diǎn)使用頁(yè)面(請(qǐng)參見 參考資料)列出了主流市場(chǎng)上的幾個(gè)計(jì)算機(jī)游戲,包括 World of Warcraft 和(家用版的)Defender,它們集成 Lua 來實(shí)現(xiàn)很多東西,從用戶界面到敵人的人工智能都可以。Lua 的其他應(yīng)用程序包括流行的 Linux 軟件更新工具 apt-rpm 的擴(kuò)展機(jī)制,還有 “Crazy Ivan” Robocup 2000 冠軍聯(lián)賽的控制邏輯。這個(gè)頁(yè)面上的很多推薦感言都對(duì) Lua 的小巧與杰出性能贊不絕口。

 

開始使用 Lua

Lua 5.0.2 版本是撰寫本文時(shí)的最新版本,不過最近剛剛發(fā)布了 5.1 版本。您可以從 lua.org 上下載 Lua 的源代碼,在 Lua-users wiki(鏈接請(qǐng)參見 參考資料)上可以找到預(yù)先編譯好的二進(jìn)制文件。完整的 Lua 5.0.2 核心文件中包括了標(biāo)準(zhǔn)庫(kù)和 Lua 編譯器,不過只有 200KB 大小。

如果您使用的是 Debian Linux,那么可以以超級(jí)用戶的身份運(yùn)行下面的命令來快速安裝 Lua 5.0

# apt-get install lua50

 

本文中給出的例子都是在 Debian Linux Sarge 上運(yùn)行的,使用的是 Lua 5.0.2 2.4.27-2-686 版本的 Linux 內(nèi)核。

在系統(tǒng)上安裝好 Lua 之后,我們可以首先來試用一下單獨(dú)的 Lua 解釋器。(所有的 Lua 應(yīng)用程序必須要嵌入到宿主應(yīng)用程序中。解釋器只是一種特殊類型的宿主,對(duì)于開發(fā)和調(diào)試工作來說非常有用。)創(chuàng)建一個(gè)名為 factorial.lua 的文件,然后輸入下面的代碼:

-- defines a factorial function
function fact (n)
  if n == 0 then
    return 1
  else
    return n * fact(n-1)
  end
end
 
print("enter a number:")
a = io.read("*number")
print(fact(a))

 

factorial.lua 中的代碼 —— 更確切地說是任何 Lua 語(yǔ)句序列 —— 都稱為一個(gè),這在上面的 Lua 特性 中已經(jīng)進(jìn)行了介紹。要執(zhí)行剛才創(chuàng)建的代碼塊,請(qǐng)運(yùn)行命令 lua factorial.lua

$ lua factorial.lua
enter a number:
10
3628800

 

或者像在其他解釋性語(yǔ)言中一樣,我們可以在代碼頂部添加一行標(biāo)識(shí)符#!),使這個(gè)腳本變成可執(zhí)行的,然后像單獨(dú)命令一樣來運(yùn)行這個(gè)文件:

$ (echo '#! /usr/bin/lua'; cat factorial.lua) > factorial 
$ chmod u+x factorial
$ ./factorial
enter a number:
4
24

 

Lua 語(yǔ)言

Lua 具有現(xiàn)代腳本語(yǔ)言中的很多便利:作用域,控制結(jié)構(gòu),迭代器,以及一組用來處理字符串、產(chǎn)生及收集數(shù)據(jù)和執(zhí)行數(shù)學(xué)計(jì)算操作的標(biāo)準(zhǔn)庫(kù)。在 Lua 5.0 Reference Manual 中有對(duì) Lua 語(yǔ)言的完整介紹(請(qǐng)參見 參考資料)。

Lua 中,只有 具有類型,而變量的類型是動(dòng)態(tài)決定的。Lua 中的基本類型(值)有 8 種: nil,布爾型,數(shù)字,字符串,函數(shù),線程,表 以及 用戶數(shù)據(jù)。前 6 種類型基本上是自描述的(例外情況請(qǐng)參見上面的 Lua 特性 一節(jié));最后兩個(gè)需要一點(diǎn)解釋。

Lua

Lua 中,表是用來保存所有數(shù)據(jù)的結(jié)構(gòu)。實(shí)際上,表是 Lua 惟一的 數(shù)據(jù)結(jié)構(gòu)。我們可以將表作為數(shù)組、字典(也稱為散列聯(lián)合數(shù)組)、樹、記錄,等等。

與其他編程語(yǔ)言不同,Lua 表的概念不需要是異構(gòu)的:表可以包含任何類型的組合,也可以包含類數(shù)組元素和類字典元素的混合體。另外,任何 Lua —— 包括函數(shù)或其他表 —— 都可以用作字典元素的鍵值。

要對(duì)表進(jìn)行瀏覽,請(qǐng)啟動(dòng) Lua 解釋器,并輸入清單 1 中的黑體顯示的代碼。


清單 1. 體驗(yàn) Lua

 
$ lua
> -- create an empty table and add some elements
> t1 = {}
> t1[1] = "moustache"
> t1[2] = 3
> t1["brothers"] = true
 
> -- more commonly, create the table and define elements
> all at once
> t2 = {[1] = "groucho", [3] = "chico", [5] = "harpo"}
> t3 = {[t1[1]] = t2[1], accent = t2[3], horn = t2[5]}
> t4 = {}
> t4[t3] = "the marx brothers"
> t5 = {characters = t2, marks = t3}
> t6 = {["a night at the opera"] = "classic"}
 
> -- make a reference and a string
> i = t3
> s = "a night at the opera"
 
> -- indices can be any Lua value
> print(t1[1], t4[t3], t6[s])
moustache   the marx brothers classic
 
> -- the phrase table.string is the same as table["string"]
> print(t3.horn, t3["horn"])
harpo   harpo
 
> -- indices can also be "multi-dimensional"
> print (t5["marks"]["horn"], t5.marks.horn)
harpo   harpo
 
> -- i points to the same table as t3
> = t4[i]
the marx brothers
 
> -- non-existent indices return nil values
> print(t1[2], t2[2], t5.films)
nil     nil     nil
 
>  -- even a function can be a key 
> t = {}
> function t.add(i,j)
>> return(i+j)
>> end
> print(t.add(1,2))
3
> print(t['add'](1,2))
3
>  -- and another variation of a function as a key 
> t = {}
> function v(x)
>> print(x)
>> end
> t[v] = "The Big Store"
> for key,value in t do key(value) end
The Big Store

 

正如我們可能期望的一樣,Lua 還提供了很多迭代器函數(shù)來對(duì)表進(jìn)行處理。全局變量 table 提供了這些函數(shù)(是的,Lua 包就是表)。有些函數(shù),例如 table.foreachi(),會(huì)期望一個(gè)從 1(數(shù)字 1)開始的連續(xù)整數(shù)范圍:

> table.foreachi(t1, print)
1 moustache
2 3

 

另外一些函數(shù),例如 table.foreach(),會(huì)對(duì)整個(gè)表進(jìn)行迭代:

> table.foreach(t2,print)
1       groucho
3       chico
5       harpo
> table.foreach(t1,print)
1       moustache
2       3
brothers        true

 

盡管有些迭代器對(duì)整數(shù)索引進(jìn)行了優(yōu)化,但是所有迭代器都只簡(jiǎn)單地處理 (key, value) 對(duì)。

現(xiàn)在我們可以創(chuàng)建一個(gè)表 t,其元素是 {2, 4, 6, language="Lua", version="5", 8, 10, 12, web="www.lua.org"},然后運(yùn)行 table.foreach(t, print) table.foreachi(t, print)

用戶數(shù)據(jù)

由于 Lua 是為了嵌入到使用另外一種語(yǔ)言(例如 C C++)編寫的宿主應(yīng)用程序中,并與宿主應(yīng)用程序協(xié)同工作,因此數(shù)據(jù)可以在 C 環(huán)境和 Lua 之間進(jìn)行共享。正如 Lua 5.0 Reference Manual 所說,userdata 類型允許我們?cè)?span lang="EN-US"> Lua 變量中保存任意的 C 數(shù)據(jù)。我們可以認(rèn)為 userdata 就是一個(gè)字節(jié)數(shù)組 —— 字節(jié)可以表示指針、結(jié)構(gòu)或宿主應(yīng)用程序中的文件。

用戶數(shù)據(jù)的內(nèi)容源自于 C,因此在 Lua 中不能對(duì)其進(jìn)行修改。當(dāng)然,由于用戶數(shù)據(jù)源自于 C,因此在 Lua 中也沒有對(duì)用戶數(shù)據(jù)預(yù)定義操作。不過我們可以使用另外一種 Lua 機(jī)制來創(chuàng)建對(duì) userdata 進(jìn)行處理的操作,這種機(jī)制稱為 元表(metatable)。

元表

由于表和用戶數(shù)據(jù)都非常靈活,因此 Lua 允許我們重載這兩種類型的數(shù)據(jù)的操作(不能重載其他 6 種類型)。元表 是一個(gè)(普通的)Lua 表,它將標(biāo)準(zhǔn)操作映射成我們提供的函數(shù)。元表的鍵值稱為事件;值(換而言之就是函數(shù))稱為元方法

函數(shù) setmetatable() getmetatable() 分別對(duì)對(duì)象的元表進(jìn)行修改和查詢。每個(gè)表和 userdada 對(duì)象都可以具有自己的元表。

例如,添加操作對(duì)應(yīng)的事件是 __add。我們可以推斷這段代碼所做的事情么?

-- Overload the add operation
-- to do string concatenation
--
mt = {}
 
function String(string)
  return setmetatable({value = string or ''}, mt)
end
 
-- The first operand is a String table
-- The second operand is a string
-- .. is the Lua concatenate operator
--
function mt.__add(a, b)
  return String(a.value..b)
end
 
s = String('Hello')
print((s + ' There ' + ' World!').value )

 

這段代碼會(huì)產(chǎn)生下面的文本:

Hello There World!

 

函數(shù) String() 接收一個(gè)字符串 string,將其封裝到一個(gè)表({value = s or ''})中,并將元表 mt 賦值給這個(gè)表。函數(shù) mt.__add() 是一個(gè)元方法,它將字符串 b 添加到在 a.value 中找到的字符串后面 b 次。這行代碼 print((s + ' There ' + ' World!').value ) 調(diào)用這個(gè)元方法兩次。

__index 是另外一個(gè)事件。__index 的元方法每當(dāng)表中不存在鍵值時(shí)就會(huì)被調(diào)用。下面是一個(gè)例子,它記住 (memoize) 函數(shù)的值:

-- code courtesy of Rici Lake, rici@ricilake.net
function Memoize(func, t)
  return setmetatable(
     t or {},
    {__index =
      function(t, k)
        local v = func(k);
        t[k] = v;
        return v;
        end
    }
  )
end
 
COLORS = {"red", "blue", "green", "yellow", "black"}
color = Memoize(
  function(node)
    return COLORS[math.random(1, table.getn(COLORS))]
    end
)

 

將這段代碼放到 Lua 解釋器中,然后輸入 print(color[1], color[2], color[1])。您將會(huì)看到類似于 blue black blue 的內(nèi)容。

這段代碼接收一個(gè)鍵值 node,查找 node 指定的顏色。如果這種顏色不存在,代碼就會(huì)給 node 賦一個(gè)新的隨機(jī)選擇的顏色。否則,就返回賦給 node 的顏色。在前一種情況中,__index 元方法被執(zhí)行一次以分配一個(gè)顏色。后一種情況比較簡(jiǎn)單,所執(zhí)行的是快速散列查找。

Lua 語(yǔ)言提供了很多其他功能強(qiáng)大的特性,所有這些特性都有很好的文檔進(jìn)行介紹。在碰到問題或希望與專家進(jìn)行交談時(shí),請(qǐng)連接 Lua Users Chat Room IRC Channel(請(qǐng)參見 參考資料)獲得非常熱心的支持。

 

嵌入和擴(kuò)展

除了語(yǔ)法簡(jiǎn)單并且具有功能強(qiáng)大的表結(jié)構(gòu)之外,Lua 的強(qiáng)大功能使其可以與宿主語(yǔ)言混合使用。由于 Lua 與宿主語(yǔ)言的關(guān)系非常密切,因此 Lua 腳本可以對(duì)宿主語(yǔ)言的功能進(jìn)行擴(kuò)充。但是這種融合是雙贏的:宿主語(yǔ)言同時(shí)也可以對(duì) Lua 進(jìn)行擴(kuò)充。舉例來說,C 函數(shù)可以調(diào)用 Lua 函數(shù),反之亦然。

Lua 與宿主語(yǔ)言之間的這種共生關(guān)系的核心是宿主語(yǔ)言是一個(gè)虛擬堆棧。虛擬堆棧與實(shí)際堆棧類似,是一種后進(jìn)先出(LIFO)的數(shù)據(jù)結(jié)構(gòu),可以用來臨時(shí)存儲(chǔ)函數(shù)參數(shù)和函數(shù)結(jié)果。要從 Lua 中調(diào)用宿主語(yǔ)言的函數(shù)(反之亦然),調(diào)用者會(huì)將一些值壓入堆棧中,并調(diào)用目標(biāo)函數(shù);被調(diào)用的函數(shù)會(huì)彈出這些參數(shù)(當(dāng)然要對(duì)類型和每個(gè)參數(shù)的值進(jìn)行驗(yàn)證),對(duì)數(shù)據(jù)進(jìn)行處理,然后將結(jié)果放入堆棧中。當(dāng)控制返回給調(diào)用程序時(shí),調(diào)用程序就可以從堆棧中提取出返回值。

實(shí)際上在 Lua 中使用的所有的 C 應(yīng)用程序編程接口(API)都是通過堆棧來進(jìn)行操作的。堆棧可以保存 Lua 的值,不過值的類型必須是調(diào)用程序和被調(diào)用者都知道的,特別是向堆棧中壓入的值和從堆棧中彈出的值更是如此(例如 lua_pushnil() lua_pushnumber()

清單 2 給出了一個(gè)簡(jiǎn)單的 C 程序(節(jié)選自 參考資料 Programming in Lua 一書的第 24 章),它實(shí)現(xiàn)了一個(gè)很小但卻功能完善的 Lua 解釋器。


清單 2. 一個(gè)簡(jiǎn)單的 Lua 解釋器

 
 1 #include <stdio.h>
 2 #include <lua.h>
 3 #include <lauxlib.h>
 4 #include <lualib.h>
 5
 6 int main (void) {
 7   char buff[256];
 8   int error;
 9   lua_State *L = lua_open();   /* opens Lua */
10   luaopen_base(L);             /* opens the basic library */
11   luaopen_table(L);            /* opens the table library */
12   luaopen_io(L);               /* opens the I/O library */
13   luaopen_string(L);           /* opens the string lib. */
14   luaopen_math(L);             /* opens the math lib. */
15
16   while (fgets(buff, sizeof(buff), stdin) != NULL) {
17     error = luaL_loadbuffer(L, buff, strlen(buff), "line") ||
18             lua_pcall(L, 0, 0, 0);
19     if (error) {
20       fprintf(stderr, "%s", lua_tostring(L, -1));
21       lua_pop(L, 1);  /* pop error message from the stack */
22     }
23   }
24
25   lua_close(L);
26   return 0;
27 }

 

2 行到第 4 行包括了 Lua 的標(biāo)準(zhǔn)函數(shù),幾個(gè)在所有 Lua 庫(kù)中都會(huì)使用的方便函數(shù)以及用來打開庫(kù)的函數(shù)。第 9 行創(chuàng)建了一個(gè) Lua 狀態(tài)。所有的狀態(tài)最初都是空的;我們可以使用 luaopen_...() 將函數(shù)庫(kù)添加到狀態(tài)中,如第 10 行到第 14 行所示。

17 行和 luaL_loadbuffer() 會(huì)從 stdin 中以塊的形式接收輸入,并對(duì)其進(jìn)行編譯,然后將其放入虛擬堆棧中。第 18 行從堆棧中彈出數(shù)據(jù)并執(zhí)行之。如果在執(zhí)行時(shí)出現(xiàn)了錯(cuò)誤,就向堆棧中壓入一個(gè) Lua 字符串。第 20 行訪問棧頂(棧頂?shù)乃饕秊?-1)作為 Lua 字符串,打印消息,然后從堆棧中刪除該值。

使用 C API,我們的應(yīng)用程序也可以進(jìn)入 Lua 狀態(tài)來提取信息。下面的代碼片段從 Lua 狀態(tài)中提取兩個(gè)全局變量:

..
if (luaL_loadfile(L, filename) || lua_pcall(L, 0, 0, 0))
  error(L, "cannot run configuration file: %s", lua_tostring(L, -1));
 
lua_getglobal(L, "width");
lua_getglobal(L, "height");
..
width = (int) lua_tonumber(L, -2);
height = (int) lua_tonumber(L, -1);
..

 

請(qǐng)?jiān)俅巫⒁鈧鬏斒峭ㄟ^堆棧進(jìn)行的。從 C 中調(diào)用任何 Lua 函數(shù)與這段代碼類似:使用 lua_getglobal() 來獲得函數(shù),將參數(shù)壓入堆棧,調(diào)用 lua_pcall(),然后處理結(jié)果。如果 Lua 函數(shù)返回 n 個(gè)值,那么第一個(gè)值的位置在堆棧的 -n 處,最后一個(gè)值在堆棧中的位置是 -1

反之,在 Lua 中調(diào)用 C 函數(shù)也與之類似。如果您的操作系統(tǒng)支持動(dòng)態(tài)加載,那么 Lua 可以根據(jù)需要來動(dòng)態(tài)加載并調(diào)用函數(shù)。(在必須使用靜態(tài)加載的操作系統(tǒng)中,可以對(duì) Lua 引擎進(jìn)行擴(kuò)充,此時(shí)調(diào)用 C 函數(shù)時(shí)需要重新編譯 Lua。)

 

結(jié)束語(yǔ)

Lua 是一種學(xué)習(xí)起來容易得難以置信的語(yǔ)言,但是它簡(jiǎn)單的語(yǔ)法卻掩飾不了其強(qiáng)大的功能:這種語(yǔ)言支持對(duì)象(這與 Perl 類似),元表使表類型具有相當(dāng)程度的可伸展性,C API 允許我們?cè)谀_本和宿主語(yǔ)言之間進(jìn)行更好的集成和擴(kuò)充。Lua 可以在 CC++C#Java? Python 語(yǔ)言中使用。

在創(chuàng)建另外一個(gè)配置文件或資源格式(以及相應(yīng)的處理程序)之前,請(qǐng)嘗試一下 LuaLua 語(yǔ)言及其社區(qū)非常健壯,具有創(chuàng)新精神,隨時(shí)準(zhǔn)備好提供幫助。

 

posted on 2009-08-26 13:27 肥仔 閱讀(1897) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 腳本語(yǔ)言

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久精品国产第一区二区三区| 影音先锋日韩资源| 亚洲综合不卡| 小嫩嫩精品导航| 欧美一区二区福利在线| 性色av一区二区三区红粉影视| 午夜在线精品偷拍| 久久久av毛片精品| 欧美区日韩区| 国产精品―色哟哟| 国产精品三级久久久久久电影| 国外精品视频| 亚洲成人在线免费| 亚洲一区二区精品视频| 欧美中文字幕久久| 欧美夫妇交换俱乐部在线观看| 亚洲国产精品成人va在线观看| 亚洲国产精品成人综合| 一本一本久久a久久精品综合妖精 一本一本久久a久久精品综合麻豆 | 亚洲激情女人| 亚洲天堂久久| 性做久久久久久久免费看| 美女精品视频一区| 国产精品乱码一区二区三区| 亚洲第一福利视频| 香港久久久电影| 亚洲国产欧美另类丝袜| 欧美一区二区三区在| 欧美激情一区二区三区在线视频观看| 国产精品久久久久久久久借妻| 亚洲第一伊人| 亚洲桃花岛网站| 国产欧美日韩一区二区三区在线观看 | 亚洲一区三区视频在线观看 | 久久成人免费日本黄色| 香港久久久电影| 欧美精品久久99久久在免费线| 国产精品久久久久久影视| 亚洲国产精品视频| 亚洲午夜av电影| 亚洲高清在线播放| 欧美伊久线香蕉线新在线| 欧美屁股在线| 亚洲二区视频| 亚洲女人天堂av| 亚洲国产综合91精品麻豆| 亚洲天堂免费观看| 欧美日韩视频在线一区二区观看视频 | 欧美视频一区二区三区四区| 国内精品视频666| 亚洲欧美国产精品专区久久| 欧美刺激午夜性久久久久久久| 日韩视频在线一区二区| 久久riav二区三区| 国产精品实拍| 亚洲性夜色噜噜噜7777| 亚洲伦理在线| 欧美日韩一区二区三区在线观看免| 91久久嫩草影院一区二区| 久久久国产一区二区三区| 亚洲午夜久久久| 国产九色精品成人porny| 一本综合久久| 亚洲人成77777在线观看网| 欧美91精品| 亚洲精品久久久久久久久久久| 美女国产一区| 免费在线国产精品| 一本久久a久久精品亚洲| 国产精品久久777777毛茸茸| 亚洲综合色婷婷| 国产欧美成人| 久久免费高清视频| 久久久久一区二区三区| 亚洲国产欧美日韩| 亚洲精品国久久99热| 欧美无砖砖区免费| 欧美一区二区三区视频免费播放| 日韩午夜免费视频| 久久久久高清| 久久久免费观看视频| 国内精品免费在线观看| 美女亚洲精品| 欧美肥婆在线| 亚洲一线二线三线久久久| 正在播放日韩| 国产一区二区三区在线观看网站| 老司机午夜精品视频| 欧美精品精品一区| 欧美怡红院视频| 久久精品国内一区二区三区| 日韩一级黄色大片| 午夜精品福利一区二区蜜股av| 伊人成人在线视频| 亚洲看片网站| 国产欧美一区二区视频| 欧美电影在线免费观看网站| 欧美日韩免费观看一区| 久久成人综合网| 欧美精品videossex性护士| 性高湖久久久久久久久| 久久中文字幕导航| 午夜精品一区二区三区在线| 免费日韩成人| 久久av免费一区| 欧美日韩精品免费观看视一区二区 | 国产精品有限公司| 亚洲福利在线看| 国产偷久久久精品专区| 亚洲欧洲精品一区二区三区波多野1战4| 国产精品久久久久久久久免费桃花| 久久久无码精品亚洲日韩按摩| 欧美日韩岛国| 欧美刺激午夜性久久久久久久| 国产精品视频不卡| 亚洲精品欧美| 国产精品久久久久久超碰| 亚洲第一中文字幕| 国产精品国产三级国产aⅴ无密码 国产精品国产三级国产aⅴ入口 | 午夜精品视频在线观看| 亚洲精品看片| 另类国产ts人妖高潮视频| 久久久久久久尹人综合网亚洲| 欧美日韩在线免费观看| 欧美aa国产视频| 国产一区自拍视频| 午夜欧美大尺度福利影院在线看| 亚洲综合视频网| 欧美精品一区二区三区蜜桃 | 久久精品91久久久久久再现| 亚洲一区精彩视频| 欧美日韩直播| 亚洲精选91| 久久激情视频久久| 亚洲高清不卡av| 男人天堂欧美日韩| 亚洲经典在线| 性色av一区二区三区在线观看 | 国产日产欧产精品推荐色| 亚洲二区三区四区| 亚洲一区二区视频在线观看| 午夜精品福利一区二区三区av | 欧美在线视频免费播放| 欧美电影电视剧在线观看| 久久午夜av| 亚洲午夜视频在线观看| 欧美激情一区二区三区在线视频观看 | 亚洲国产精品高清久久久| 亚洲综合色视频| 欧美激情一区二区三区四区 | 免费不卡视频| 亚洲国产精品视频一区| 久久se精品一区二区| 99这里有精品| 欧美一区二区三区在线免费观看| 国内成人精品一区| 国产日韩欧美精品一区| 9色porny自拍视频一区二区| 中文亚洲欧美| 91久久精品一区二区别| 欧美中文在线视频| 亚洲黄色精品| 1769国产精品| 久久精品亚洲乱码伦伦中文| 欧美成人有码| 欧美伊人久久久久久久久影院 | 亚洲免费大片| 最新日韩中文字幕| 欧美在线视频免费播放| 99热这里只有精品8| 久久综合给合| 裸体一区二区| 亚洲国产一区二区视频| 久久日韩粉嫩一区二区三区| 翔田千里一区二区| 欧美日韩国产综合视频在线观看中文| 老司机午夜精品| 91久久综合亚洲鲁鲁五月天| 亚洲深夜福利| 欧美在线不卡| 国产一区91精品张津瑜| 亚洲一级片在线观看| 亚洲伊人网站| 国产精品国产三级欧美二区| 亚洲国产精品女人久久久| 国产乱码精品1区2区3区| 亚洲性图久久| 欧美尤物巨大精品爽| 国产一区清纯| 欧美国产日本在线| 午夜日韩av| 欧美freesex8一10精品| 久久午夜精品一区二区| 国产在线国偷精品产拍免费yy| 女人香蕉久久**毛片精品| 亚洲理论电影网| 久久综合伊人77777尤物| 亚洲美女区一区| 欧美午夜寂寞影院| 久久国产视频网|