Luaバイナリをソースファイルからコンパイルして作成するとき、
標準では静的ライブラリが生成されます。
通常Luaを組み込み用途で使用するときは静的ライブラリで十分なのですが、
時には共有ライブラリが欲しくなるので、作成してみます。
(lua5.1を想定しています)
src/Makefileに以下を追加する。
LUA_O=lua.oと書かれた行の下に、以下の行を挿入する。
LUA_SO=liblua5.1.so
次の行の最後に、$(LUA_SO)を追記する。
ALL_T=$(LUA_A) $(LUA_T) $(LUAC_T)
↓
ALL_T=$(LUA_A) $(LUA_T) $(LUAC_T) $(LUA_SO)
clean:と書かれた行の前に、以下の2行を挿入する。
(2行の前後には1行の空行があるようにする)
$(LUA_SO): $(CORE_O) $(LIB_O)
$(CC) -o $@ -shared $?
保存する。
次にMakefileを下記のように編集する。
TO_LIB= liblua.aとなっている行の最後に liblua5.1.soを追記する。
↓
TO_LIB=liblua.a liblua5.1.so
これで、makeするとliblua5.1.soが生成されます。
admin Lua liblua5.1.so, lua, コンパイル, 共有ライブラリ
PHPのcall_user_func関数って便利です。
イベント駆動系のプログラムを書くときには必須です。
そんな関数がLuaにはない・・・ (見つけられないだけかも知れませんが)
ということで、試作してみました。
function call_user_func(func, ...)
local t = type(func)
if t == 'function' then
return func(...)
elseif t == 'string' then
if _G[func] == nil or type(_G[func]) ~= 'function' then
error("function is not defined '"..func.."'")
end
return _G[func](...)
elseif t == 'table' then
local _instance = func[1]
local _method = func[2]
if _instance == nil or _method == nil then
error("instance or method name is nil")
end
if _instance[_method] == nil then
error("class method is not defined '".._method.."'")
end
return _instance[_method](_instance, ...)
else
error("func is not matched type '"..type(func).."'")
end
end
function funcA(name)
print("My name is "..name)
end
Class = {}
function Class:new(name)
local t = {name = name}
setmetatable(t, {__index = Class})
return t
end
function Class:funcA()
print("I am "..self.name)
end
function Class:funcB(...)
self:funcA()
print("data are "..table.concat({...}, ","))
end
a = Class:new("taro")
a:funcA()
a:funcB("1", "2", "3")
call_user_func({a, "funcB"}, "a", "b", "c")
call_user_func(funcA, "jiro")
call_user_func("funcA", "saburo")
実行結果は正常
I am taro
I am taro
data are 1,2,3
I am taro
data are a,b,c
My name is jiro
My name is saburo
19行目の_instance[_method](_instance, …)が肝です。
メソッドの第1引数はインスタンスを格納しなければならないオキテがあります。
よって、直接引数を…にしてしまうと、おかしなことになりますから注意!
admin Lua call_user_func, lua