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 ...
随机推荐
- 计算机网络(4): socket select使用:聊天室模版
知识点: 如上所示,用户首先将需要进行IO操作的socket添加到select中,然后阻塞等待select系统调用返回.当数据到达时,socket被激活,select函数返回.用户线程正式发起read ...
- 吴裕雄--天生自然MySQL学习笔记:MySQL简介
MySQL 是最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System:关系数据库管理系统)应用 ...
- druid socket timeout超时15分钟(转载)
背景 在应用端通过mybatis的interceptor自定义Plugin拦截Executor, 统计输出sql的执行耗时. 今天生产发生一个很奇怪的问题: 莫名其妙卡顿15分钟+,其后正常返回sql ...
- 60年前美国军方的这个编程原则,造就了多少伟大的框架--KISS原则
摘自:https://kb.cnblogs.com/page/654057/ 作者: 贺卓凡 来源: ImportSource 发布时间: 2020-01-23 19:52 阅读: 2324 次 ...
- tensorflow deeplabv3 训练自己的数据集
https://blog.csdn.net/malvas/article/details/90776327
- python实现图书管理系统
# 用户注册 def logon(): print("欢迎来到图书管理系统注册页面~") username = input("请输入用户名:") if len( ...
- 封装FTP类
using System; using System.Net; using System.Net.Sockets; using System.Text; using System.IO; using ...
- CodeForces 990D Graph And Its Complement(图和补图、构造)
http://codeforces.com/problemset/problem/990/D 题意: 构造一张n阶简单无向图G,使得其连通分支个数为a,且其补图的连通分支个数为b. 题解: 第一眼看到 ...
- Andorid Studio 3.1 引入第三方jar包的方法
今天手痒,把android studio 从3.0升级到3.1.2 发现很多问题 1.发现编译会下载好多东西,等半天 2.之前的jar包导不进来了 针对jar包导入不成功,我查了一下说是不支撑comp ...
- MTF的倾斜边缘计算方法
光学系统性能的衡量方法有很多,常见的有点扩散函数法.瑞利判断法.点 列图法.光学传递函数(MTF)法等,其中 MTF 法在光学系统和镜头加工制造中 使用 最为广泛.MTF 曲线真实的反映了成像系统将物 ...