Lua 模塊與包
模塊類似於一個封裝庫,從 Lua 5.1 開始,Lua 加入了標准的模塊管理機制,可以把一些公用的代碼放在一個文件里,以 API 接口的形式在其他地方調用,有利於代碼的重用和降低代碼耦合度。
Lua 的模塊是由變量、函數等已知元素組成的 table,因此創建一個模塊很簡單,就是創建一個 table,然后把需要導出的常量、函數放入其中,最后返回這個 table 就行。以下為創建自定義模塊 m.lua,文件代碼格式如下:
-- 文件名為 m.lua -- 定義一個名為 m 的模塊 module = {} -- 定義一個常量 module.constant = "這是一個常量" module.table = {key1="val1","val2"} -- 定義一個函數 function module.func1() io.write("這是一個公有函數!\n") end local function func2() print("這是一個私有函數!") end function module.func3() func2() end module.func4 = func2; module.func5 = function() print("func5!!!") end return module
加載機制
對於自定義的模塊,模塊文件不是放在哪個文件目錄都行,函數 require 有它自己的文件路徑加載策略,它會嘗試從 Lua 文件或 C 程序庫中加載模塊。
require 用於搜索 Lua 文件的路徑是存放在全局變量 package.path 中,當 Lua 啟動后,會以環境變量 LUA_PATH 的值來初始這個環境變量。如果沒有找到該環境變量,則使用一個編譯時定義的默認路徑來初始化。
當然,如果沒有 LUA_PATH 這個環境變量,也可以自定義設置,在當前用戶根目錄下打開 .profile 文件(沒有則創建,打開 .bashrc 文件也可以),例如把 "~/lua/" 路徑加入 LUA_PATH 環境變量里:
export LUA_PATH="~/lua/?.lua;;"
//文件名為luaLoad.c,定義一個可供lua調用的模塊 #include <lua.h> #include <lauxlib.h> #include <lualib.h> static int add(lua_State *L) { double d1 = luaL_checknumber(L, 1); double d2 = luaL_checknumber(L, 2); lua_pushnumber(L, d1+d2); return 1; } int luaopen_luaLoad(lua_State *L) { luaL_Reg luaLoadFun[] = { {"add",add}, {NULL,NULL} }; luaL_newlib(L,luaLoadFun); return 1; }
編譯上面這個luaLoad.c文件為luaLoad.so文件
gcc luaLoad.c -fPIC -shared -o luaLoad.so -I/home/ubuntu/Downloads/lua-5.3.4/src
-I后面是lua的安裝路徑,里面包含了上面include的那幾個頭文件
--testModule.lua測試調用上面兩個模塊 local luaLoad = require "luaLoad" print(luaLoad.add(1,2)) local m = require("m") print(m.constant) for key,val in pairs(m.table) do print(key,val) end m.func1() m.func3() m.func4() m.func5() m.func2()
ubuntu@dongyang-K46CB:~/lua$ lua testModule.lua
3.0
這是一個常量 1 val2 key1 val1
這是一個公有函數! 這是一個私有函數! 這是一個私有函數! func5!!! lua: testModule.lua:15: attempt to call a nil value (field 'func2') stack traceback: testModule.lua:15: in main chunk [C]: in ?
