cocos2d-x使用的lua版本号为5.1,使用的是luaL_register()函数来进行批量注册。下面说一下在5.3版本怎样批量注册函数。先以luaL_openlibs()函数为例。
static const luaL_Reg loadedlibs[] = {
{"_G", luaopen_base},
{LUA_LOADLIBNAME, luaopen_package},//package
{LUA_COLIBNAME, luaopen_coroutine},//coroutine
{LUA_TABLIBNAME, luaopen_table},//table
{LUA_IOLIBNAME, luaopen_io},//io
{LUA_OSLIBNAME, luaopen_os},//os
{LUA_STRLIBNAME, luaopen_string},//string
{LUA_MATHLIBNAME, luaopen_math},//math
{LUA_UTF8LIBNAME, luaopen_utf8},//utf8
{LUA_DBLIBNAME, luaopen_debug},//debug
#if defined(LUA_COMPAT_BITLIB)
{LUA_BITLIBNAME, luaopen_bit32},
#endif
{NULL, NULL}
};
LUALIB_API void luaL_openlibs (lua_State *L) {
const luaL_Reg *lib;
/* "require" functions from 'loadedlibs' and set results to global table */
for (lib = loadedlibs; lib->func; lib++) {
luaL_requiref(L, lib->name, lib->func, 1);
lua_pop(L, 1); /* remove lib */
}
}
luaL_openlibs()会遍历loadedlibs数组,并调用luaL_requiref函数,对于这个函数,官网上这么解释:
void luaL_requiref (lua_State *L, const char *modname, lua_CFunction openf, int glb);
If modname
is not already present in package.loaded
, calls function openf
with string modname
as an argument and sets the call result in package.loaded[modname]
, as if that function has been called through require
.
If glb
is true, also stores the module into global modname
.
Leaves a copy of the module on the stack.
如果在package.loaded中不存在nodname这个字段,就调用openf这个函数,并且把返回值命名为modname,同时赋值给package.loaded[modname](相当于 require)。如果glb为true的话,会存储这个模块为_G[modname]。并且会留下拷贝到栈中。
因此luaL_openlibs()的功能就是:遍历数组,加载对应的模块并赋值,之后清除栈中的副本。
接下来以math模块为例:
static const luaL_Reg mathlib[] = {
{"abs", math_abs},
{"acos", math_acos},
{"asin", math_asin},
{"atan", math_atan},
{"ceil", math_ceil},
{"cos", math_cos},
{"deg", math_deg},
{"exp", math_exp},
{"tointeger", math_toint},
{"floor", math_floor},
{"fmod", math_fmod},
{"ult", math_ult},
{"log", math_log},
{"max", math_max},
{"min", math_min},
{"modf", math_modf},
{"rad", math_rad},
{"random", math_random},
{"randomseed", math_randomseed},
{"sin", math_sin},
{"sqrt", math_sqrt},
{"tan", math_tan},
{"type", math_type},
#if defined(LUA_COMPAT_MATHLIB)
{"atan2", math_atan},
{"cosh", math_cosh},
{"sinh", math_sinh},
{"tanh", math_tanh},
{"pow", math_pow},
{"frexp", math_frexp},
{"ldexp", math_ldexp},
{"log10", math_log10},
#endif
/* placeholders */
{"pi", NULL},
{"huge", NULL},
{"maxinteger", NULL},
{"mininteger", NULL},
{NULL, NULL}
};
/*
** Open math library
*/
LUAMOD_API int luaopen_math (lua_State *L) {
luaL_newlib(L, mathlib);
lua_pushnumber(L, PI);
lua_setfield(L, -2, "pi");
lua_pushnumber(L, (lua_Number)HUGE_VAL);
lua_setfield(L, -2, "huge");
lua_pushinteger(L, LUA_MAXINTEGER);
lua_setfield(L, -2, "maxinteger");
lua_pushinteger(L, LUA_MININTEGER);
lua_setfield(L, -2, "mininteger");
return 1;
}
在luaopen_math函数中,先创建了一个注册了mathlib数组函数的table,并放入栈顶。之后在这个table中添加了"pi" "huge" "maxinteger" "mininteger"字段,此时在栈中存在的就是luaL_newlib创建的table。然后在lua_openlibs()中给这个table命名为math。在mathlib数组的后面添加了几个等字段如huge的原因只是起到一个占位符的作用,即证明在math包里存在这个字段,删去亦可。
综上,如果我们要批量注册的话,我们可以先调用luaL_newlib函数创建一个table,之后调用luaL_requiref函数为这个table赋值并放入_G以及赋值给package.loaded中,然后再调用lua_pop(1)清除副本即可。