当在userdata上调用__len元方法时,Lua向C传递两个参数,分别是nil和userdata。那么nil参数是用来做什么的呢?
2011-2-6 2:24:43
收藏:0
阅读:179
评论:1
这是一个小的 C 测试程序,用来演示我看到了什么。它注册了一个新的 Lua 对象类型并执行一个 Lua 脚本。当脚本调用 __len
元方法时,我期望只有一个参数会被传递到堆栈上 - 对象的 userdata。然而它传递了 userdata 和一个神秘的 nil。
len.c
:
包括 <stdio.h>
#include <lua5.1/lua.h>
#include <lua5.1/lauxlib.h>
#include <lua5.1/lualib.h>
#define OBJECT_LEN 123456
/* 虚拟的对象 */
typedef struct {
int length;
} object;
/* 创建新对象并将对象长度设置为 OBJECT_LEN */
static int object_new( lua_State *L ) {
object *new = lua_newuserdata( L, sizeof( object ) );
new->length = OBJECT_LEN;
luaL_getmetatable( L, "metatable" );
lua_setmetatable( L, 1 );
return 1;
}
/* 获取对象的长度 */
static int object_len( lua_State *L ) {
/* 打印 Lua 的堆栈 - 总是有 2 个参数,userdata 和 nil */
static const char *const lua_types[] = {
"nil", "boolean", "light userdata", "number", "string",
"table", "function", "userdata", "thread",
};
int arg_count = lua_gettop( L );
int i;
for ( i = arg_count; i > 0; -- i ) {
int type = lua_type( L, i );
printf( "%d:%s\n", i, lua_types[ type ] );
}
/* 将对象的长度推入 Lua 的堆栈 */
object *obj = luaL_checkudata( L, 1, "metatable" );
lua_pop( L, 2 ); /* 弹出神秘的 'nil' 和 userdata */
lua_pushinteger( L, obj->length );
return 1;
}
static const luaL_reg object_constructor[] = {
{ "new", object_new },
{ NULL, NULL }
};
static const luaL_reg object_methods[] = {
{ "__len", object_len },
{ NULL, NULL }
};
int main( int argc, char **argv ) {
lua_State *L = lua_open();
luaL_openlibs( L );
/* 创建 'object' 类型 */
luaL_newmetatable( L, "metatable" );
lua_pushvalue( L, -1 );
lua_setfield( L, -2, "__index" );
luaL_register( L, NULL, object_methods );
luaL_register( L, "object", object_constructor );
lua_pop( L, 2 );
/* 运行 Lua 脚本 */
int result = luaL_dofile( L, "meta.lua" );
if ( result != 0 ) {
fprintf( stderr, "error:%s\n", lua_tostring( L, 1 ) );
}
lua_close( L );
return 0;
}
meta.lua
: 创建一个对象并打印它的长度。
obj = object.new()
print( "obj length:", #obj )
编译并执行:
$ gcc -Wall len.c -o len -llua5.1 && ./len
2:nil
1:userdata
obj length: 123456
为什么堆栈上有一个 nil?
原文链接 https://stackoverflow.com/questions/4911112
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
这是一个“不重要的实现细节”。
请参见 这个 lua-l 信息线程。