目录

  1. 数组操作
  2. 字符串操作
  3. 在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:

大专栏  Lua 学习 chapter30 编写c函数的技巧 - Jow的博客">

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的博客的更多相关文章

  1. Step By Step(编写C函数的技巧)

    Step By Step(编写C函数的技巧) 1. 数组操作:    在Lua中,"数组"只是table的一个别名,是指以一种特殊的方法来使用table.出于性能原因,Lua的C ...

  2. Docker学习总结(6)——通过 Docker 化一个博客网站来开启我们的 Docker 之旅

    通过 Docker 化一个博客网站来开启我们的 Docker 之旅 这篇文章包含 Docker 的基本概念,以及如何通过创建一个定制的 Dockerfile 来 Docker 化Dockerize一个 ...

  3. iOS超全开源框架、项目和学习资料汇总(5)AppleWatch、经典博客、三方开源总结篇

    完整项目 v2ex – v2ex 的客户端,新闻.论坛.apps-ios-wikipedia – apps-ios-wikipedia 客户端.jetstream-ios – 一款 Uber 的 MV ...

  4. 【Python】模块学习之Timer定时任务,递归定时自调获取博客浏览量

    Timer定时任务 下面是Timer函数的官方doc介绍信息 """ Call a function after a specified number of second ...

  5. Django学习案例一(blog):六. 开发博客内容页面

    目标:某条博客具体内容的展示,可返回博客主页面,可进行评论. 1. 编辑路由 一篇博客,要将其找出来,就需要有一个唯一的标识.Django 的模型中默认有一个唯一的且未自增长的主键,即 id 字段.我 ...

  6. WordPress 3.8 中文正式版下载 - 建站与学习首选!全球最流行的开源PHP博客网站程序

    转载自:http://www.iplaysoft.com/wordpress.html 话说虽然我一直都在网站底部写着本站基于 WordPress 构建,但时常还是有人问我网站是用什么程序建的,还真有 ...

  7. C#学习日志 day8 -------------- async await 异步方法入门(引用博客)以及序列化和反序列化的XML及json实现

    首先是异步方法的介绍,这里引用自http://www.cnblogs.com/LoveJenny/archive/2011/11/01/2230933.html async and await 简单的 ...

  8. React Router学习笔记(转自阮一峰老师博客)

    React Router是一个路由库,通过管理URL来实现组件切换和状态转变. 1.安装和使用 $ npm install -S react-router 在使用时,作为React组件导入 impor ...

  9. 学做酷炫有爱的免费网页,学习 Github Page 教你分分钟搭建自己的博客

    Github Page 网页搭建教程,教你分分钟搭建自己的博客 很多其它美丽的网页搭建教程教程.请看这里:http://www.duobei.com/course/8506331668 waterma ...

随机推荐

  1. shift+alt 可对notepadplusplus 打开的文档进行列操作

    shift+alt 可对notepadplusplus 打开的文档进行列操作

  2. 计算机utf-8/gbk/utf-16对照表

    GBK   UTF-16 UTF-8 ==================D2BB  4E00  E4 B8 80  一B6A1  4E01  E4 B8 81  丁C6DF  4E03  E4 B8 ...

  3. TCP/IP通信过程

    一.参考网址 1.以太网帧格式.IP数据报格式.TCP段格式+UDP段格式 详解 2. 二.TCP的建立过程 1.例子: 192.168.22.66 telenet到192.168.22.74的tcp ...

  4. dotnet core 链接mongodb

    导入命名空间 using MongoDB.Bson; using MongoDB.Driver; 测试示例: var client = new MongoClient("mongodb:// ...

  5. 吴裕雄--天生自然ShellX学习笔记:Shell 输入/输出重定向

    大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回​​到您的终端.一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端.同样,一个命令通常将其输出写入到标准输出,默 ...

  6. python编程:从入门到实践----基础知识>第4章练习

    4-1 比萨 :想出至少三种你喜欢的比萨,将其名称存储在一个列表中,再使用for 循环将每种比萨的名称都打印出来. a.修改这个for 循环,使其打印包含比萨名称的句子,而不仅仅是比萨的名称.对于每种 ...

  7. 剑指offer【09】- 跳台阶

    题目:一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果). 对于本题,前提只有 一次 1阶或者2阶的跳法. a.如果两种跳法,1阶或者 ...

  8. js实现新闻滚动-单行滚动或者多行滚动

    注明:都是转载. 先说单行滚动: --------直接复制以下代码即可试验 转载http://www.3lian.com/edu/2011/06-30/4986.html----------- < ...

  9. bad SQL grammar []; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException

    ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL ...

  10. C++ lock_guard 互斥锁

    概述根据对象的析构函数自动调用的原理,c++11推出了std::lock_guard自动释放锁,其原理是:声明一个局部的lock_guard对象,在其构造函数中进行加锁,在其析构函数中进行解锁.最终的 ...