Lua 用户自定义类型
userdata:lua提供的一种基本类型
userdata提供了一块原始的内存区域,可以用来存储任何东西。同时,Lua中没有对userdata的任何预定义操作。
//根据指定大小分配内存,并将对应的userdata压入栈,最后返回这个内存块的地址
void lua_newuserdata(lua_State*L,size_t size);
元表
针对不同类型的userdata,创建一个唯一的元表。每当创建一个userdata后,就用相应的元表来标识他。lua不能修改userdata的元表,也就无法欺骗代码。
通常,可以将userdata的元表信息放在注册表(REGISTRYINDEX),f辅助库中提供了
//创建一个新的table做元表,并将其压入栈,同时将其与注册表中指定名称关联起来
int luaL_newmetatable(lua_State*L,const char* tname);
//检索与tname相关的元表
void luaL_getmetatable(lua_State*L,const char* tname);
//检查栈的指定位置是否为元表,并且是否具有和指定名称相匹配的表
//如果正确,返回userdata的地址,否则引发一个错误
void* luaL_checkudata(lua_State*L,int index,const char*tname);
lua
//使用元表的方式,注册新类型
int luaopen_array(lua_State*L){
luaL_newmetatable(L,"LuaBook.array");
luaL_register(L,"array",arrayLib);
return 1
}
static int newarray(lua_State*L){
...
luaL_getmetatable(L,"LuaBook.array");//压入栈
lua_setmetatable(L,-2);//userdata在-2
return 1;/*新的userdata已经在栈中*/
}
//lua库中的会从栈中弹出一个table,并将其设定为指定索引对象的元表。
lua_setmetatable(L,index);
面向对象的访问
static const struct luaL_Reg arrarylib_f[] = {
{"new",newarray},
{NULL,NULL}
};
static const struct luaL_Reg arraylib_m[] = {
{"set",setarray},
....
{NULL,NULL}
};
//创建metatable并添加__index(table方式)
int luaopen_array(lua_State*L){
luaL_newmetatable(L,"LuaBook.array");
/*元表.__index==元表*/
lua_pushvalue(L,-1);//复制元表
lua_setfield(L,-2,"__index");
lua_register(L,NULL,arraylib_m);//会使用栈顶的table注册函数
lua_register(L,"array",arraylib_f);//会创建一个新table并注册指定函数
}
轻量级的userdata
内存有C控制,只需要将内存的地址传给lua
//将一个轻量级userdata放入堆栈
void lua_pushlightuserdata(lua_State*L,void*p);
网友评论