lua中的table、stack和registery
ok,前面准备给一个dll写wrapper,写了篇日志,看似写的比较明白了,但是其实有很多米有弄明白的。比如PIL中使用的element,key,tname,field这些,还是比较容易混淆的。今天正好搞搞清楚。
1、stack
这个应该不用多讲了,C和lua中的交互就是基于一个stack的,而且每次lua调用一个c函数,都是给分配一个新的stack。它的原型:
typedef int (*lua_CFunction) (lua_State *L);
stack中的基本单元在PIL中多成为element。
2、table
我们可以在C中定义一个struct如下:
struct ColorTable {
char *name;
unsigned char red, green, blue;
} colortable[] = {
{"WHITE", MAX_COLOR, MAX_COLOR, MAX_COLOR},
{"RED", MAX_COLOR, , },
{"GREEN", , MAX_COLOR, },
{"BLUE", , , MAX_COLOR},
{"BLACK", , , },
...
{NULL, , , } /* sentinel */
};
在C中,我们事实上可以把如上的struct当做类似下面lua代码来用:
WHITE = {r=, g=, b=}
RED = {r=, g=, b=}
...
How?我们先定义一个自己的setfield,用来往在堆顶的table中添加member“name=value”:
#define MAX_COLOR 255 /* assume that table is at the top */
void setfield (const char *name, int value) {
lua_pushstring(L, name);
lua_pushnumber(L, (double)value/MAX_COLOR);
lua_settable(L, -);
}
然后,我们创建某个颜色的table:
void setcolor (struct ColorTable *ct) {
lua_newtable(L); /* creates a table */
setfield("r", ct->red); /* table.r = ct->r */
setfield("g", ct->green); /* table.g = ct->g */
setfield("b", ct->blue); /* table.b = ct->b */
lua_setglobal(L, ct->name); /* `name' = table */
}
利用上面的两段代码,我们在L中创建了一个某个颜色的table,比如setcolor(colortable[1]),事实上是往L中放了一个表格,WHITE = {r = 1, g = 1, b = 1}。把整个struct都放入,只需使用下面这个循环:
int i = ;
while (colortable[i].name != NULL)
setcolor(&colortable[i++]);
自此,我们上面struct中所有的颜色都有了一张自己的table。
所以,field只是某个table中的,一个“name=value”对,name通常是一个字符串。这里的name也就是通常说的index,使用任意的lua认可的值都可以用来做它的name。这样一个“name=value”对被称为一个field。
3、registery
registery和其它的lua的表没什么却别。我们可以通过一个伪index(pesudo-index)在L中找到它;这个伪index是由宏LUA_REGISTRYINDEX定义的。我们也可以把这个伪index当做是普通的index来使用,但是不同的是,需要知道,它的value也不是在L里面。它的value不在stack中这一点非常重要,它决定了那些对stack本身做操作的函数是不适用的,比如lua_remove和lua_insert。
我们可以用下面的语句取到在registery中的,关键词为“key”的注册项:
lua_pushstring(L, "Key");
lua_gettable(L, LUA_REGISTRYINDEX);
因为他和其它的表没有区别,那么,和操作其它表一样操作它就好了。不过,因为所有的C库使用同一张registery,所以,命名上面我们要下些功夫,以免发生命名冲突。PIL里面推荐了一种保险的做法,我们可以选择一个我们代码里的静态变量的地址作为key:链接器不会给不同的静态变量分配相同地址,所以就不用担心重复问题了。如果要这么做,你需要调用函数lua_pushlightuserdata。在lua中,userdata就是一个普通的C value,而lightuserdata则是指C指针。我们在这里调用它把某个指针放到堆顶。具体可以看下面代码:
/* variable with an unique address */
static const char Key = 'k'; /* store a number */
lua_pushlightuserdata(L, (void *)&Key); /* push address */
lua_pushnumber(L, myNumber); /* push value */
/* registry[&Key] = myNumber */
lua_settable(L, LUA_REGISTRYINDEX); /* retrieve a number */
lua_pushlightuserdata(L, (void *)&Key); /* push address */
lua_gettable(L, LUA_REGISTRYINDEX); /* retrieve value */
myNumber = lua_tonumber(L, -); /* convert to number */
当然,你也可以使用字符串作为registery的key,去多长都可以,你认为达到目的了就行。后面的懒得翻译了囧RZ
For such keys, there is no bulletproof method of choosing names, but there are some good practices, such as avoiding common names and prefixing your names with the library name or something like it. Prefixes like lua or lualib are not good choices. Another option is to use a universal unique identifier (uuid), as most systems now have programs to generate such identifiers (e.g., uuidgen in Linux). An uuid is a -bit number (written in hexadecimal to form a string) that is generated by a combination of the host IP address, a time stamp, and a random component, so that it is assuredly different from any other uuid.
lua中的table、stack和registery的更多相关文章
- Lua中使用table实现的其它5种数据结构
Lua中使用table实现的其它5种数据结构 lua中的table不是一种简单的数据结构,它可以作为其他数据结构的基础,如:数组,记录,链表,队列等都可以用它来表示. 1.数组 在lua中,table ...
- 递归打印lua中的table
在lua中,table是比较常用的数据形式,有时候为了打印出里面的内容,需要做一些特殊处理. 废话不多讲,直接粘代码: print = release_print -- 递归打印table local ...
- lua中遍历table的几种方式比较
当我在工作中使用lua进行开发时,发现在lua中有4种方式遍历一个table,当然,从本质上来说其实都一样,只是形式不同,这四种方式分别是: for key, value in pairs(tbtes ...
- Lua中的table函数库
table.concat(table, sep, start, end) concat是concatenate(连锁, 连接)的缩写. table.concat()函数列出参数中指定table的数组 ...
- lua中求table长度
关于lua table介绍,看以前的文章http://www.cnblogs.com/youxin/p/3672467.html. 官方文档是这么描述#的: 取长度操作符写作一元操作 #. 字符串的长 ...
- Lua中的table构造式(table constructor)
最简单的构造式就是一个空构造式{},用于创建一个空table. 构造式还可以用于初始化数组.例如,以下语句:days = {"Sunday", "Monday" ...
- lua中求table长度--(转自有心故我在)
关于lua table介绍,看以前的文章http://www.cnblogs.com/youxin/p/3672467.html. 官方文档是这么描述#的: 取长度操作符写作一元操作 #. 字符串的长 ...
- Lua中获取table长度
-- table.getn(tableName) 得到一个table的大小,等同于操作符# -- 要注意的是:该table的key必须是有序的,索引是从1开始的. --例如有序的 local xian ...
- lua中使用table实现类和继承
--因为只有当读写不存在的域时,才会触发__index和__newindex classA = {className = "classA",name="classAIns ...
随机推荐
- TopCoder
在TopCoder下载好luncher,网址:https://www.topcoder.com/community/competitive%20programming/ 选择launch web ar ...
- Expression Blend4经验分享:制作一个简单的文字按钮样式
首先在Grid里放一个TextBlock,对象时间线窗口的结构树如下 右键点击grid,选择构成控件 会弹出构成控件的对话框,选择你要构成的控件类型,控件名称,控件样式存储位置 这里我们选择butto ...
- 支付宝Cookie高危漏洞引发的思考
背景:当时我在做公司的网站支付接入,在调试支付宝WAP支付时,发现一些匪夷所思的事情: 1.我想要切换账号时退到需要输入登录信息时,原账号并没有退出,我按一下后退键又回来了: 2.我关闭浏览器也没有退 ...
- 最小/大费用最大流模板(codevs1914)
void addedge(int fr,int to,int cap,int cos){ sid[cnt].fr=fr;sid[cnt].des=to;sid[cnt].cap=cap;sid[cnt ...
- N-gram模型
n元语法 n-gram grammar 建立在马尔可夫模型上的一种概率语法.它通过对自然语言的符号串中n个符号同时出现概率的统计数据来推断句子的结构关系.当n=2时,称为二元语法,当 ...
- javascript面试题(一)
答案和解析在问题下一行,为白色字体 单选题 1.以下哪条语句会产生运行错误:(a) A.var obj = ();//语法错误 B.var obj = [];//创建数组 C.var obj = {} ...
- 【原创】解决jquery在ie中不能解析字符串类型xml结构的xml字符串的问题
$.fn.extend({ //此方法解决了ie中jquery不识别非xml的类型的xml字符串的问题 tony tan findX: function (name) { if (this & ...
- 从库查看状态的时候显示“ Last_Error”
mysql> show slave status\G;*************************** 1. row *************************** ...
- python 中的sort 和java中的Collections.sort()函数的使用
x=[1,2,3] x.sort()对的,x这个都变了 y=x.sort()错误 y=sorted(x)对的,x拍好序的一个副本 python中用匿名函数和自定义函数排序:(很奇怪的是比较函数返回的是 ...
- JS中的事件类型和事件属性的基础知识
周末无聊, 这几天又复习了下JS搞基程序设计3, 想着好记性不如浪笔头哇, 要么把这些东西写下来, 这样基础才能更加扎实么么哒, 知道的同学也可以直接过一下,当做复习, 小姨子再也不用担心我的学习啦 ...