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. ...
随机推荐
- Python--进阶处理8
# ====================第八章:类与对象========================= # --------------改变对象的字符串显示------------------ ...
- wordpress 忘记密码
update wp_users set user_pass=md5("123456") where user_login='帐号';
- How to Design a Good API and Why it Matters
前谷歌首席 Java 架构师谈如何设优秀的 API – 码农网 http://www.codeceo.com/article/google-java-good-api.html 2015-11-24 ...
- vue系列
1.vue基础 2.vue请求和跨域 3.自定义全局组件 4.vue-router 5.Vuex
- Wow! Such Doge!---hdu4847(字符串水题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4847 题意就是求给出的文章中共有多少个doge,不区分大小写直接用strstr做就可以了: #incl ...
- 具体解释linux下的串口通讯开发
串行口是计算机一种经常使用的接口,具有连接线少.通讯简单,得到广泛的使用.经常使用的串口是RS-232-C接口(又称EIA RS-232-C)它是在1970年由美国电子工业协会(EIA)联合贝尔系统. ...
- Selenium的PageFactory & PageObject 在大型项目中的应用
因为最近遇到的技术问题一直没找到可行的解决办法,一直在翻看selenium的源代码,之前写测试代码的时候就是拿来即用,写什么功能啊,就按手动的操作步骤去转换,近日看到一个文章,又去wiki上查了查,觉 ...
- Linux系统——shell脚本
shell脚本编程 作用:通过命令行解析的方式,自动执行设定好的程序或命令代码.(若将脚本挂到定时任务中,就会自动在非工作时间里自动触发执行程序) Shell脚本文件以“.sh”结尾 规范的Shell ...
- jQuery HTML操作学习笔记
学习资料 jQuery教程 获取 1.获取.设置元素的内容 1.1获取或设置目标元素的文本内容 语法 $(selector).text(); 获取元素文本内容 $(selector).text(con ...
- C# 使用 Windows API 发送文件到打印机
最近需要做一个打印的功能,于是在网上找到了这么一个方法. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public cl ...