lua5.3中luaL_setfunc设置upvalue的用法示例
缘起
luaL_setfuncs 这个函数可以注册c函数到lua,另外还可以设置闭包函数使用的变量upvalue. 我没有用过,在 云风的skynet 才第一次见过,于是写个例子实际使用以下.
函数原型:
void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);
文档定义:
Registers all functions in the array l (see luaL_Reg) into the table on the top of the stack (below optional upvalues, see next).
When nup is not zero, all functions are created sharing nup upvalues, which must be previously pushed on the stack on top of the library table. These values are popped from the stack after the registration.
意思是第三个参数 nup 如果非零, 则所有通过luaL_setfuncs注册的函数都共享 nup个 upvalues. 这些 upvalues 必须在注册之前 pushed 到栈上.
实例
实例是在lua5.3环境下面,编写导处的一个lua能用动态库.
环境搭建
我用的centos7.0,自带lua5.1.下载5.3源码并编译
wget https://www.lua.org/ftp/lua-5.3.4.tar.gz
tar -xzvf lua-5.3.4.tar.gz
cd lua-5.3.4
make linux
编写要导出的lua库
lua_mytest.c
#include <lua.h>
#include <lauxlib.h>
static int add(lua_State *L){
double op1 = luaL_checknumber(L,1);
double op2 = luaL_checknumber(L,2);
//将函数的结果压入栈中。如果有多个返回值,可以在这里多次压入栈中。
lua_pushnumber(L,op1 + op2);
//返回值用于提示该C函数的返回值数量,即压入栈中的返回值数量。
return 1;
}
static int add_with_upvalue(lua_State *L){
int k = lua_tonumber(L, lua_upvalueindex(1));
const char* another_upvalue = lua_tostring(L, lua_upvalueindex(2));
printf("second upvalue is %s\n",another_upvalue);
double op1 = luaL_checknumber(L,1);
double op2 = luaL_checknumber(L,2);
//将函数的结果压入栈中。如果有多个返回值,可以在这里多次压入栈中。
lua_pushnumber(L,op1 + op2+k);
//返回值用于提示该C函数的返回值数量,即压入栈中的返回值数量。
return 1;
}
static const luaL_Reg no_upvalue_func[] = {
{"add", add},
{0, 0}
};
static const luaL_Reg with_upvalue_func[] = {
{"add_with_upvalue", add_with_upvalue},
{0, 0}
};
LUALIB_API int luaopen_mytest(lua_State * L) {
lua_newtable(L);
/*register function no upvalue*/
luaL_setfuncs(L, no_upvalue_func, 0);
/*set two upvalue */
lua_pushnumber(L,100);
lua_pushstring(L,"i am upvalue");
/*register function with two upvalue*/
/*push了两个upvalue值所以第三个参数是2*/
luaL_setfuncs(L, with_upvalue_func, 2);
return 1;
}
MyMakeFile 编译mytest.so
all:
gcc -Wall -O2 -shared -o mytest.so lua_mytest.c -fPIC -llua -I. -lm -L/home/gsx/work/lua_study/lua-5.3.4/src
clean:
rm -f mytest.so
执行命令 make -f MyMakeFile ,生成mytest.so
test.lua
local mytest = require "mytest"
ret = mytest.add(10,20)
print(ret)
ret = mytest.add_with_upvalue(10,20)
print(ret)
测试
lua test.lua
output:
30.0
second upvalue is i am upvalue
130.0
注意事项
- test.lua 和 mytest.so放在同一个目录.
- 如果编译mytest.so的过程中报错. /usr/bin/ld: /usr/local/lib/liblua.a(lapi.o): relocation R_X86_64_32 against `luaO_nilobject_' can not be used when making a shared object; recompile with -fPIC /usr/local/lib/liblua.a: could not read symbols: Bad value, 则重新编译 liblua.a,在 lua的MakeFile 的CFLAG里面增加 -fPIC即可.
总结
例子通过注册一个不带有upvalue和带有两个upvalue的简单函数说明了luaL_setfuncs的作用.
lua5.3中luaL_setfunc设置upvalue的用法示例的更多相关文章
- python中的随机函数random的用法示例
python中的随机函数random的用法示例 一.random模块简介 Python标准库中的random函数,可以生成随机浮点数.整数.字符串,甚至帮助你随机选择列表序列中的一个元素,打乱一组数据 ...
- STL中map,set的基本用法示例
本文主要是使用了STL中德map和set两个容器,使用了它们本身的一些功能函数(包括迭代器),介绍了它们的基本使用方式,是一个使用熟悉的过程. map的基本使用: #include "std ...
- 用 SwitchHosts设置hotst, 用法示例
涉及到本地默认ip(localhost,127.0.0.1)设置关联地址时,使用XAMPP本地服务器时避免自动跳转设置的域名的一些处理方法 打开此文件,把内容修改如下 # Virtual Hosts# ...
- 标准C++中的string类的用法总结
标准C++中的string类的用法总结 相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的确,MFC中的CString类使用起来真的非常的方便好用.但是如果离开了MFC框架,还有 ...
- 【转】java.util.vector中的vector的详细用法
[转]java.util.vector中的vector的详细用法 ArrayList会比Vector快,他是非同步的,如果设计涉及到多线程,还是用Vector比较好一些 import java.uti ...
- jquery中attr()与prop()函数用法实例详解(附用法区别)
本文实例讲述了jQuery中attr()与prop()函数用法.分享给大家供大家参考,具体如下: 一.jQuery的attr()方法 jquery中用attr()方法来获取和设置元素属性,attr是a ...
- oracle中to_date详细用法示例(oracle日期格式转换)
这篇文章主要介绍了oracle中to_date详细用法示例,包括期和字符转换函数用法.字符串和时间互转.求某天是星期几.两个日期间的天数.月份差等用法 TO_DATE格式(以时间:2007-11-02 ...
- .NET中代理服务器WebProxy的各种用法
引用地址 引用 因为涉及到代理的各种情况,WebRequest和WebProxy类的文档写的相当复杂,不但各个文档关注点不同,而且不同版本的同一文档也有小小的区别,网上也没有关于这个类的相关文章.于是 ...
- Vue基础01vue的基本示例,vue的双向数据绑定,vue中常见的几种用法,vue相关常见指令
自学vue框架,每天记录重要的知识点,与大家分享!有不足之处,希望大家指正. 本篇将讲述:vue的基本示例,vue的双向数据绑定,vue中常见的几种用法,vue相关常见指令 前期学习基础,使用vue. ...
随机推荐
- CSS Sprites 原理技术介绍及其优化方法
先期的准备工作 应对一个项目后期维护成本大的问题,我们最好的解决方案就是在开始前制定一系列的规范来限制问题的产品.好的开始是成功的一半.对于CSS Sprites,在项目开始前,我们要充分认识一个产品 ...
- Ubuntu 分区以及各个挂载目录的基本含义
我磁盘大概还有70多G的空间吧,我全部拿来使用的.真实的双系统哦. 一般来讲,linux系统分区最少要包括/和/swap两个.这样据说会影响性能,没有这样安装过,就无从考证啦.其实就是重装系统的时候, ...
- python基础-第十三篇-13.1web框架本质
基础与概念 众所周知,对于所有的web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端 web框架分两类:一类是包括socket和业务逻辑(tornado),另一 ...
- Quartz 的使用
1. Quartz 入门案例 1.1 Quartz 相关jar包 quartz-2.2.3.jar quartz-jobs-2.2.3.jar 1.2 创建任务类 // 自定义任务类 public c ...
- IIS7.5 错误代码0x8007007e HTTP 错误 500.19
目录 问题案例 解决问题 参考资料 问题案例 今天在win2008+IIS7.5的环境中部署WCF服务后,一直出现无法打开的页面.具体错误信息如下: HTTP 错误 500.19 - Internal ...
- shell_02
if判断: if [$? -eq 0];then echo "xxxxxxxxxxx" else echo "xxxxxxxxxxxxx" fi case判断: ...
- SpringBoot-基于Maven工程使用SpringBoot
Spring Boot SpringBoot是一个社区反馈推动的项目.SpringBoot可以说是至少五年来Spring乃至整个Java社区最有影响力的项目之一.SpringBoot主要包括以下特性: ...
- Keras + Ubuntu环境搭建
安装Theano (环境参数:Ubuntu 16.04.2 Python 2.7) 安装 numpy 和 scipy 1.sudo apt-get install python-numpy pyth ...
- springboot设置返回值的编码
/** * @param params * @return 志诚阿福 来访问 */ @PostMapping(value = "/fromAFu", produces = &quo ...
- Linux使用scp命令实现文件的上传和下载
上传本地/data/project/test.zip 文件至远程服务器192.168.1.2的 /root 目录下,代码如下: scp /home/project/test.zip root@192 ...