LuaにC関数を登録する方法はありますが、グローバルコンテキストではなく、テーブルフィールドとして登録しますか?
2 に答える
これはluaL_register()
、1 つ以上の関数に対して意図されていることです。標準的な使用法は、C で記述されたモジュールのセットアップの一部です。
/* actual definitions of modA() and modB() are left as an exercise. */
/* list of functions in the module */
static const luaL_reg modfuncs[] =
{
{ "a", modA},
{ "b", modB},
{ NULL, NULL }
};
/* module loader function called eventually by require"mod" */
int luaopen_mod(lua_State *L) {
luaL_register(L, "mod", modfuncs);
return 1;
}
これにより、 と という名前の 2 つの関数を持つ「mod」という名前のモジュールが作成されmod.a
ますmod.b
。
のマニュアルを引用luaL_register(L,libname,l)
:
libname
equal to で呼び出すとNULL
、リストl
( を参照luaL_Reg
) 内のすべての関数をスタックの一番上のテーブルに登録するだけです。null 以外で呼び出されると、新しい table を作成し、
libname
それ をグローバル変数の値として設定し、それを の値として設定し、 list 内のすべての関数を登録します。または variable にテーブルがある場合 、新しいテーブルを作成する代わりに、このテーブルを再利用します。luaL_register
t
libname
package.loaded[libname]
l
package.loaded[libname]
libname
いずれにせよ、関数はテーブルをスタックの一番上に残します。
luaL_register()
NULL
テーブルがスタックの一番上にある限り、2 番目のパラメーターを渡すことにより、任意のテーブルに C 関数を配置するために使用できます。
void register_c_function(char const * const tableName, char const * const funcName, CFunctionSignature funcPointer)
{
lua_getfield(lstate, LUA_GLOBALSINDEX, tableName); // push table onto stack
if (!lua_istable(lstate, -1)) // not a table, create it
{
lua_createtable(lstate, 0, 1); // create new table
lua_setfield(lstate, LUA_GLOBALSINDEX, tableName); // add it to global context
// reset table on stack
lua_pop(lstate, 1); // pop table (nil value) from stack
lua_getfield(lstate, LUA_GLOBALSINDEX, tableName); // push table onto stack
}
lua_pushstring(lstate, funcName); // push key onto stack
lua_pushcfunction(lstate, funcPointer); // push value onto stack
lua_settable(lstate, -3); // add key-value pair to table
lua_pop(lstate, 1); // pop table from stack
}