tolua++その4(hook関数)
http://www.codenix.com/~tolua/tolua++.html#customizing
toluaコマンドの"-L"オプションでhook関数を上書きできる(元は、basic.luaに空の関数が書いてある)。
doit.lua:doit() ↓ package.lua:Package() ↓ preprocess_hook(p) ↓ p:preprocess() ↓ preparse_hook(p) ↓ p:parse() ↓ parser_hook(s) ↓ ######################################################### # パッケージのパースが終わり ######################################################### ↓ pre_output_hook(p) ↓ p:preamble() p:supcode() ↓ pre_register_hook(p) ↓ p:register() ↓ post_output_hook(p)
他のは細かすぎてわからなかったので放置した。
パッケージファイルをパース後、クラスに関数を追加したいときなんかはpre_output_hookを使えばよいと思う。
たとえば、こんなwindow.pkgを作って
$#include "window.h" namespace win32 { class Window { void draw(); void show(bool isShow); void move(int x, int y); void resize(int w, int h); }; }
こいつに
int setMouseLeftPressCallback(lua_State *L);
というlua関数を引数に取れるメソッドを足してやりたい時に、hook関数で後付けで追加することができる。
hook関数上書きようのluaスクリプトを用意。hook.lua
-- packageツリーをたどって名前の一致するものを探す local function find(p, name) if p.name==name then return p end for i, v in ipairs(p) do if type(v)=='table' then local found=find(v, name) if found then return found end end end return nil, '"'..name..'" not found' end -- 対象のパッケージに関数を追加する local function appendTo(p, target, f) local t=assert(find(p, target)) if t then print("found: ", target, t) setmetatable(f, { __index=classFunction}) table.insert(t, f) end end -- hook関数上書き function pre_output_hook(p) appendTo(p, "win32::Window", { lname="setMouseLeftPressCallback", -- いったんstaticまたは通常のc関数でthisポインタを取得する必要がある cname="win32::Window::setMouseLeftPressCallback", }) p:print() end
こんなんでパッケージの任意の場所にCの任意の関数またはstaticクラス関数を追加できる。
# -Lオプション $ tolua -L hook.lua window.pkg
typedef int (*lua_CFunction) (lua_State *L);
型のものを特別扱いする方法がわからないので無理やりやっているのでこうなっている。
特別扱いする方法はありそうなのだが・・・
ちょうど去年やっていたところをまたやっているw
http://d.hatena.ne.jp/ousttrue/20100225/1267071607