-
Notifications
You must be signed in to change notification settings - Fork 1
C_Function
C で実装した関数を Lua から呼び出すには、あらかじめ lua_register などを使って、Lua 側からアクセスできるようにしておく必要がある。
void lua_register (lua_State *L, const char *name, lua_CFunction f);
ここで、name は Lua からみた時の関数名で、グローバルな名前空間上に登録される。関数本体は lua_CFunction という型で、Lua から呼ばれる C の関数は、必ずこの型でなくてはいけない。
lua_CFunction の型は次のように宣言されている。
typedef int (*lua_CFunction) (lua_State *L);
まず、戻り値は整数で、これは C から Lua へ返す値の数を表す。Lua の関数は多値を返すことができるので、2 個以上の値を返しても良い。また、関数の実行結果によって、返す値の数が変わっても良い。(「多値と引数」の項を参照)
関数本体のとる引数は、lua_State のポインタのみである。この L を通じて、Lua から C に渡された引数を取得できる。
C から Lua の関数を呼び出す時と同様に、C の関数へ渡された引数はスタックを使って表される。たとえば、Lua 側から次のような関数呼び出しをしたとする。
a, b, c = c_func(123, "abc")
すると、スタックには数値の 123 と文字列の "abc" が、この順番にプッシュされている。となると、スタックを上から見たときには、"abc"、123 の順番で値が入っていることになる。しかしいちいちこの逆順の順番を考えるのは面倒なので、便宜上、スタック中のそれぞれの引数を、渡された順番に、-1、-2 というマイナスのインデックスで指定することができる。
ではここで、まず第 1 引数を数値として取り出すには、lua_tonumber という関数を使う。
lua_Number lua_tonumber (lua_State *L, int index);
第 1 引数を取り出すには前述の通り、index に -1 を渡せば良いので、次のようになる。
double first_arg = lua_tonumber(L, -1);
同様に、第 2 引数を文字列として取り出すには、lua_tostring という関数を使う。
const char *lua_tostring (lua_State *L, int index);
今度は第 2 引数なので index には -2 を渡す。すると、コードは次のようになる。
const char *second_arg = lua_tostring(L, -2);
なお、lua_tostring は、C の文字列を想定している。すなわち、文字列の最後は必ずナル文字で終わっていて、かつ、文字列中にナル文字 '\0' が含まれていない場合にのみ正しく動作する。