Lua 学习 chapter30 编写c函数的技巧 - Jow的博客
目录
- 数组操作
- 字符串操作
- 在c函数中保存状态
生活总需要一点仪式感,然后慢慢的像那个趋向完美的自己靠近。
数组操作
Lua中的数组就是以特殊的方式使用边。像lua_setttable and lua_gettable这种用来操作的通用函数,也可以用于操作数组,不过C API为使用整数索引的表访问和更新提供了专门的函数:
1
2
void lua_geti (lua_State *L, int index, int key);
void lua_seti (lua_State *L, int index, int key);
lua_geti相当于:
1
2
lua_pushnumber(L, key);
lua_gettable(L,t);
lua_seti相当于:
1
2
3
lua_pushnumber(L, key);
lua_insert(L, -2);
lua_settable(L,t);
eg:函数map,该函数对数组中的所有元素调用一个指定的函数,然后用此函数返回的结果替换掉对应的数组元素。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int l_map(lua_State* L) {
int i, n;
luaL_checktype(L, 1, LUA_TTABLE); //确保指定的参数具有指定的类型
luaL_checktype(L, 2, LUA_TFUNCTION);
n = luaL_len(L, 1); //类似长度运算符
for (int i = 0; i < n; i++)
{
lua_pushvalue(L, 2);
lua_geti(L, 1, i);
lua_call(L, 1, 1); //类似以pcall但是会传播错误,而不是返回错误码
lua_seti(L, 1, i);
}
return 0;
}
字符串操作
当c函数接收到一个lua字符串为参数是,必须遵守两条规则,在使用字符串期间不能从栈中将其弹出,而且不应该修改字符串。
标准API为两种最用的字符串操作提供了支持,即字符串提取和字符串连接。要提取子串,那么基本的操作lua_pushlstring可以获取字符串长度作为额外的参数。因此,如果要把字符串s从i到j(include)的子串传递给lua:
1
lua_pushlstring(L, s + i, j - i +1);
eg:函数根据分隔符来分隔字符串:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static int l_split(lua_State* L) {
const char* s = luaL_checkstring(L, 1);
const char* sep = luaL_checkstring(L, 2);
const char* e;
int i = 1;
lua_newtable(L);
while ((e = strchr(s, *sep)) != NULL)
{
lua_pushlstring(L, s, e - s);
lua_rawseti(L, -2, i++);
s = e + 1;
}
lua_pushstring(L, s);
lua_rawseti(L, -2, i);
return 1;
}
在c函数中保存状态
C API提供了两个类似的地方来存储非局部数据,即注册表(registry)和上值(upvalue).
注册表
注册表是一张只能被C代码访问的全局表。通常情况下,我们使用注册表来存储多个模块间的共享数据。
注册表总是位于伪索引LUA_REGISTRYINDEX中。伪索引就像是一个栈中的索引,但是它所关联的值不在栈中。lua API中大多数接受索引作为参数的函数也能将伪索引作为参数,像lua_remove和lua_insert这种操作栈本身的函数除外。eg:获取注册表中键为“key”的值,可以使用如下的调用。
1
2
3
4
5
6
7
8
lua_getfield(L, LUA_REGISTRYINDEX, "Key");
static char key = 'k'
lua_pushstring(L, mystr);
lua_rawsetp(L,LUA_REGISTRYINDEX,(void *) &key);//设置值到注册表中
lua_rawgetp(L,LUA_REGISTRYINDEX,(void *) &key);//从注册表中取值
mystr = lua_tostring(L,-1);
Lua 学习 chapter30 编写c函数的技巧 - Jow的博客的更多相关文章
- Step By Step(编写C函数的技巧)
Step By Step(编写C函数的技巧) 1. 数组操作: 在Lua中,"数组"只是table的一个别名,是指以一种特殊的方法来使用table.出于性能原因,Lua的C ...
- Docker学习总结(6)——通过 Docker 化一个博客网站来开启我们的 Docker 之旅
通过 Docker 化一个博客网站来开启我们的 Docker 之旅 这篇文章包含 Docker 的基本概念,以及如何通过创建一个定制的 Dockerfile 来 Docker 化Dockerize一个 ...
- iOS超全开源框架、项目和学习资料汇总(5)AppleWatch、经典博客、三方开源总结篇
完整项目 v2ex – v2ex 的客户端,新闻.论坛.apps-ios-wikipedia – apps-ios-wikipedia 客户端.jetstream-ios – 一款 Uber 的 MV ...
- 【Python】模块学习之Timer定时任务,递归定时自调获取博客浏览量
Timer定时任务 下面是Timer函数的官方doc介绍信息 """ Call a function after a specified number of second ...
- Django学习案例一(blog):六. 开发博客内容页面
目标:某条博客具体内容的展示,可返回博客主页面,可进行评论. 1. 编辑路由 一篇博客,要将其找出来,就需要有一个唯一的标识.Django 的模型中默认有一个唯一的且未自增长的主键,即 id 字段.我 ...
- WordPress 3.8 中文正式版下载 - 建站与学习首选!全球最流行的开源PHP博客网站程序
转载自:http://www.iplaysoft.com/wordpress.html 话说虽然我一直都在网站底部写着本站基于 WordPress 构建,但时常还是有人问我网站是用什么程序建的,还真有 ...
- C#学习日志 day8 -------------- async await 异步方法入门(引用博客)以及序列化和反序列化的XML及json实现
首先是异步方法的介绍,这里引用自http://www.cnblogs.com/LoveJenny/archive/2011/11/01/2230933.html async and await 简单的 ...
- React Router学习笔记(转自阮一峰老师博客)
React Router是一个路由库,通过管理URL来实现组件切换和状态转变. 1.安装和使用 $ npm install -S react-router 在使用时,作为React组件导入 impor ...
- 学做酷炫有爱的免费网页,学习 Github Page 教你分分钟搭建自己的博客
Github Page 网页搭建教程,教你分分钟搭建自己的博客 很多其它美丽的网页搭建教程教程.请看这里:http://www.duobei.com/course/8506331668 waterma ...
随机推荐
- Django框架(七):模型(三) 关联、模型类的属性
1. 关联 1.1 模型类关系 关系型数据库的关系包括三种类型: ForeignKey:一对多,将字段定义在多的一端中. ManyToManyField:多对多,将字段定义在任意一端中. OneToO ...
- Java类只加载一次的情况
一个类只加载一次: 调用Java命令. 创建对象时 访问静态成员时 Class.forName("包名.类名")
- NOIp2017TG解题报告
NOIp2018RP++! 虽然没去但还得写写QAQ D1T1 : 小凯的疑惑 数学题 手推几组数据然后发现规律 \(Ans = (a-1)(b-1)+1\) AC in 1minite D1T2 : ...
- POJ 1845 Sumdiv [素数分解 快速幂取模 二分求和等比数列]
传送门:http://poj.org/problem?id=1845 大致题意: 求A^B的所有约数(即因子)之和,并对其取模 9901再输出. 解题基础: 1) 整数的唯一分解定理: 任意正整数都有 ...
- Android圆角布局、天气应用、树状图、日食动画、仿饿了么导航效果等源码
Android精选源码 Android通用圆角布局源码 Android天气应用源码,界面美观 一个支持定制的树状 Android 自定义View PIN 码专用输入控件,支持任意长度和输入任意数据 A ...
- JavaScript中Promise 使用、原理以及实现过程
1.什么是 Promise promise 是目前 JS 异步编程的主流解决方案,遵循 Promises/A+ 方案. 2.Promise 原理简析 (1)promise 本身相当于一个状态机,拥有三 ...
- 代码验证ncut和谱聚类的系数
W = rand(30); W = W+W'; I = cell(3,1); I{1} = 1:10; I{2} = 11:20; I{3} = 21:30; vol = -ones(3,1); fo ...
- idea高效插件
RestfulToolkit:url定位controller,快捷键:ctrl+\Maven Helper:依赖分析JRebel:热部署Rainbow Brackets:个性化花括号aiXcode:a ...
- 树莓派切换到root用户
1:如何修改pi账号密码 passwd pi 2:开启root账户 树莓派使用的linux是debian系统,所以树莓派启用root和debian是相同的 debian里root账户默认没有密码,但账 ...
- kubernets轻量 contain log 日志收集技巧
首先这里要收集的日志是容器的日志,而不是集群状态的日志 要完成的三个点,收集,监控,报警,收集是基础,监控和报警可以基于收集的日志来作,这篇主要实现收集 不想看字的可以直接看代码,一共没几行,尽量用调 ...