English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
I moduli sono simili a una libreria di contenimento; a partire da Lua 5.1, Lua ha introdotto un meccanismo di gestione dei moduli standard, che permette di mettere alcune parti di codice comune in un file e di chiamarli tramite un'interfaccia API in altri luoghi, favorendo la riutilizzabilità del codice e riducendo la complessità delle dipendenze.
I moduli Lua sono composti da elementi conosciuti come variabili, funzioni ecc., quindi creare un modulo è molto semplice: basta creare una tabella, aggiungere al suo interno le costanti e le funzioni da esportare e infine restituire questa tabella. Ecco un esempio di file di codice per creare un modulo personalizzato module.lua:
-- Nome del file module.lua -- Definire un modulo chiamato module module = {} -- Definire una costante module.constant = "Questa è una costante" -- Definire una funzione function module.func1() io.write("Questa è una funzione pubblica!\n") end local function func2() print("Questa è una funzione privata!") end function module.func3() func2() end return module
Da ciò si può dedurre che la struttura del modulo è una struttura di table, quindi è possibile operare e chiamare le costanti o le funzioni del modulo come se fossero elementi di una table.
Come sopra, la dichiarazione func2 è una variabile locale del blocco del programma, il che significa che è una funzione privata e non può essere acceduta dall'esterno al funzionamento privato del modulo, che deve essere chiamato tramite la funzione pubblica del modulo.
Lua fornisce una funzione chiamata require per caricare moduli. Per caricare un modulo, è sufficiente chiamarlo semplicemente. Ad esempio:
require("<nome_modulo>")
O
require "<nome_modulo>"
Dopo l'esecuzione di require, viene restituito un table composto da costanti o funzioni del modulo, e viene anche definito un variabile globale che contiene questo table.
Il risultato dell'esecuzione del codice sopra è:
Questa è una costante Questa è una funzione privata!
O definire un alias per il modulo caricato per facilitare la chiamata:
Il risultato dell'esecuzione del codice sopra è:
Questa è una costante Questa è una funzione privata!
Per i moduli personalizzati, il percorso del file del modulo non è importante in qualsiasi directory, la funzione require ha la sua propria strategia di caricamento del percorso del file, che tenta di caricare il modulo da un file Lua o da una libreria di programma C.
Il percorso di ricerca dei file Lua utilizzato da require è salvato nella variabile globale package.path, quando Lua viene avviato, inizializzerà questa variabile globale con il valore dell'ambiente variabile LUA_PATH. Se non viene trovato tale ambiente variabile, verrà utilizzato un percorso predefinito definito durante la compilazione per inizializzare.
Naturalmente, se non esiste l'ambiente variabile LUA_PATH, è possibile configurarlo personalmente, aprendo il file .profile nel directory principale dell'utente (se non esiste, aprire il file .bashrc anche), ad esempio aggiungere il percorso "~/lua/" all'ambiente variabile LUA_PATH:
#LUA_PATH export LUA_PATH="~/lua/?.lua;;"
I percorsi dei file sono separati dal simbolo ";", gli ultimi due ";;" rappresentano il percorso aggiunto più il percorso predefinito originale.
Poi, aggiornare i parametri dell'ambiente variabile, in modo che diventino immediatamente efficaci.
source ~/.profile
A questo punto, supponiamo che il valore di package.path sia:
/Users/dengjoe/lua/?.lua;./?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/lib/lua/5.1/?.lua;/usr/local/lib/lua/5.1/?/init.lua
Quindi, quando si chiama require("module") verranno cercati i seguenti percorsi di directory per il file di destinazione.
/Users/dengjoe/lua/module.lua; ./module.lua /usr/local/share/lua/5.1/module.lua /usr/local/share/lua/5.1/module/init.lua /usr/local/lib/lua/5.1/module.lua /usr/local/lib/lua/5.1/module/init.lua
Se è stato trovato il file di destinazione, verrà chiamata package.loadfile per caricare il modulo. Altrimenti, verrà cercata la libreria del programma C.
Il percorso del file di ricerca è ottenuto dalla variabile globale package.cpath, che è inizializzata tramite l'ambiente LUA_CPATH.
La strategia di ricerca è la stessa dell'altro, ma ora la ricerca è per file di tipo so o dll. Se trovati, require li caricherà tramite package.loadlib.
Lua 和 C 很容易结合,使用 C 为 Lua 写包。
与 Lua 中写包不同,C 包在使用之前必须首先加载并连接,在大多数系统中最容易的实现方式是通过动态连接库机制。
Lua 在一个叫 loadlib 的函数内提供了所有的动态连接的功能。这个函数有两个参数:库的绝对路径和初始化函数。所以典型的调用实例如下:
local path = "/usr/local/lua/lib/libluasocket.so" local f = loadlib(path, "luaopen_socket")
loadlib 函数加载指定的库并且连接到 Lua,然而它并不打开库(也就是说没有调用初始化函数),反之它返回初始化函数作为 Lua 的一个函数,这样我们就可以直接在 Lua 中调用它。
如果加载动态库或者查找初始化函数时出错,loadlib 将返回 nil 和错误信息。我们可以修改前面一段代码,使其检测错误然后调用初始化函数:
local path = "/usr/local/lua/lib/libluasocket.so" -- 或者 path = "C:\\windows\\luasocket.dll",这是 Window 平台下 local f = assert(loadlib(path, "luaopen_socket")) f() -- 真正打开库
一般情况下我们期望二进制的发布库包含一个与前面代码段相似的 stub 文件,安装二进制库的时候可以随意放在某个目录,只需要修改 stub 文件对应二进制库的实际路径即可。
将 stub 文件所在的目录添加到 LUA_PATH,这样设置后就可以使用 require 函数加载 C 库了。