目录

  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. 剑指offer【08】- 二叉树的深度(java)

    题目:二叉树的深度 考点:知识迁移能力 题目描述:输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 牛客网上的剑指offer题, ...

  2. CMake变量(提供信息的变量)

    目录 CMAKE_VERSION CMAKE_MAJOR_VERSION CMAKE_MINOR_VERSION CMAKE_PATCH_VERSION CMAKE_TWEAK_VERSION CMA ...

  3. 本地搭建3节点kubernetes

    kubernetes本地搭建版本选择 CentOS Linux release 7.7.1908 kubernetesVersion: v1.17.0 weave-kube:2.6.0 ceph/ce ...

  4. Juniper srx新增接口IP,使PC直连srx(转)

    转自:https://www.jianshu.com/p/bc27134bde3d Juniper srx新增接口IP,使PC直连srx 2018.11.19 14:24:15字数 424 概述 需求 ...

  5. UML-类图-关键字如何使用?

    部分预定义UML关键字: 例如: 加上关键字,明确,清晰.

  6. 将iso mount 到nfs 目录问题

    最近有个需求,需要在多台系统安装程序,安装文件是iso 格式的,最普通的办法就是拷贝到其它系统,然后mount loop 到本地目录. 但是比较麻烦,而且当前已经有一个nfs 服务端了,于是想出一个办 ...

  7. Idea创建Spring项目

    环境 win7 + Idea2018 Classpath commons-logging-1.2 + spring-framework-4.1.6.RELEASE Step1 创建工程 File -& ...

  8. Tooltips

    #include<windows.h> #include<Commctrl.h> #include"resource.h" #pragma comment( ...

  9. 给c盘瘦身

    火狐浏览器缓存 C:\Users\lenovo\AppData\Local\Mozilla\Firefox\Profiles\5nk022sw.default\cache2\entries ‪C:\U ...

  10. vue-resource HTTP API基础

    vue-resource特点 vue-resource插件具有以下特点: 1. 体积小 vue-resource非常小巧,在压缩以后只有大约12KB,服务端启用gzip压缩后只有4.5KB大小,这远比 ...