前節では,関数をグローバル関数として定義しました.
しかし,関数が増えてくると名前の衝突などが起こってしまう場合があります.
そういった事態を避けるため,
テーブル内に関数を定義するといった方法が取られます.
次のようなサンプルコードを書いてみます.
まずはLua側のコードです.
--sample.lua
x, y = 5, 10
print( x .. " + " .. y .. " = " .. myMath.add(x, y) )
print( x .. " * " .. y .. " = " .. myMath.mul(x, y) )
myMathテーブルにあるadd関数とmul関数を呼び出しています.
では,テーブルに関数を登録するCのサンプルコードをお見せします.
#include <stdio.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
int l_add(lua_State* L)
{
//第1引数 intとして取得
int x = luaL_checkint(L, -2);
//第2引数
int y = luaL_checkint(L, -1);
int result = x + y;
printf("%d + %d を計算します\n", x, y);
//戻り値をスタックに積む
lua_pushnumber(L, result);
return 1; //戻り値の数を指定
}
int l_mul(lua_State* L)
{
//第1引数 intとして取得
int x = luaL_checkint(L, -2);
//第2引数
int y = luaL_checkint(L, -1);
int result = x * y;
printf("%d * %d を計算します\n", x, y);
//戻り値をスタックに積む
lua_pushnumber(L, result);
return 1; //戻り値の数を指定
}
//登録する関数
static const struct luaL_Reg myMathLib [] = {
{"add", l_add},
{"mul", l_mul},
{NULL, NULL} //最後は必ずNULLのペア
};
int main (void)
{
int x = 10, y = 5;
//Luaを開く
lua_State* L = luaL_newstate();
//Luaの標準関数を使用できる状態にする
luaL_openlibs(L);
//add, mulをmyMathテーブルに登録
luaL_register(L, "myMath", myMathLib);
//Luaファイルsample.luaを読み込む
if( luaL_loadfile(L, "sample.lua") || lua_pcall(L, 0, 0, 0) ) {
printf("sample.luaを開けませんでした\n");
printf("error : %s\n", lua_tostring(L, -1) );
return 1;
}
lua_close(L);
return 0;
}
実行結果
5 + 10 を計算します
5 + 10 = 15
5 * 10 を計算します
5 * 10 = 50
luaL_reg構造体は以下のように定義されています.
typedef struct luaL_Reg {
const char *name;
lua_CFunction func;
} luaL_Reg;
name側にはLua側に登録したい関数名を,funcにはC言語関数を渡します.
myMathテーブルを新たに作成し,luaL_reg構造体で定義した関数を登録するためには
luaL_register関数を使用します.