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 ...
随机推荐
- mysql 基本知识 以及优化
msql的索引应用 1.hash索引 等于值比较时 2.tree索引 范围比较 like '%%'
- dozer
1.简介 dozer是用来两个对象之间属性转换的工具,有了这个工具之后,我们将一个对象的所有属性值转给另一个对象时,就不需要再去写重复的set和get方法了. 2.如果两个类之间的属性有些属性意思一样 ...
- nginx调整large_client_header_buffers
https://nginx.org/en/docs/http/ngx_http_core_module.html#large_client_header_buffers Syntax: large_c ...
- selenium滚动条应用,爬永远讲不完的故事
from selenium import webdriver class Lj(object): def __init__(self): self.driver = webdriver.Chrome( ...
- UVA 515 差分约束 SPFA判负
第一次看这个题目,完全不知道怎么做,看起来又像是可以建个图进行搜索,但题目条件就给了你几个不等式,这是怎么个做法...之后google了下才知道还有个差分约束这样的东西,能够把不等式化成图,要求某个点 ...
- 201604-2 俄罗斯方块 Java
大家谁能帮我看看是哪里不对,提交到系统中是0分,在Eclipse中可以得出例子中的结果 思路: 题目中有两个关键点:如何模拟下落的过程,如何判断方块下落在哪里停止. 在数据的存储上,需要保存整个&qu ...
- Python cannot import name 'Line' from 'pyecharts'
问题与尝试 代码 from pyecharts.charts import Line 中,出现 cannot import name 'Line' from 'pyecharts' 错误. 找了很多, ...
- ZJNU 1125 - A == B ?——中级
处理后再判断即可,处理过程注意考虑全面. /* Written By. StelaYuri */ #include<iostream> #include<string> usi ...
- Dynamics CRM - Plug-in Class 和 Workflow Class 的用法与区别
在 Dynamics CRM 开发中,我们可以使用 JavaScript 在前端对 Entity Form 进行数据操作,与此同时,我们也可以使用 C# 写后台插件,其中就包括了 Plug-in Cl ...
- eclipse导入项目报错解决方法
1.导入项目之前,请确认工作空间编码已设置为utf-8:window->Preferences->General->Wrokspace->Text file encoding- ...