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. ...
随机推荐
- 1. Action 实现 ModelDriven 接口后的运行流程
1). 先会执行 ModelDrivenInterceptor 的 intercept 方法. public String intercept(ActionInvocation invocation) ...
- 【转】SignalR来做实时Web聊天
本章和大家分享的内容是使用Signal R框架创建个简易的群聊功能,主要讲解如何在.Net的MVC中使用这个框架,由于这个项目有官方文档(当然全英文),后面也不打算写分享篇了,主要目的是让朋友们在需要 ...
- 让IIS8支持WCF的最简单方法
以前在IIS8中使用WCF时,总是参考在IIS8添加WCF服务支持这篇博文进行手工设置: 1. 首先添加MIME类型:扩展名“.svc”,MIME类型 “application/octet-strea ...
- Cassandra go语言client使用
关于什么是cassandra,可以参考: http://blog.csdn.net/zyz511919766/article/details/38683219 http://cassandra.apa ...
- linux物理页面的换入换出简析
2017-04-25 我们都知道,现代操作系统使用分页机制和虚拟内存,同时为了提高物理页面的利用率,采用了请求调页的机制,即物理内存的分配只有在真正需要的时候才会进行,比如发生了真正的读写操作,而普通 ...
- int文档
文档 class int(object): """ int(x=0) -> integer int(x, base=10) -> integer ------ ...
- 【opencv入门篇】 10个程序快速上手opencv【下】
导言:本系列博客目的在于能够在vs快速上手opencv,理论知识涉及较少,大家有兴趣可以查阅其他博客深入了解相关的理论知识,本博客后续也会对图像方向的理论进一步分析,敬请期待:) 上篇传送:http: ...
- phpcms调用子栏目名称/文章怎么操作
phpcms调用子栏目名称相对比较简单一些,也是用{pc:content}来调用,只是把action设置为category,catid如果为0的话是调用所有一级栏目,如果是其他数字的话,则调用相应栏目 ...
- 3D游戏引擎中常见的三维场景管理方法
对于一个有很多物体的3D场景来说,渲染这个场景最简单的方式就是用一个List将这些物体进行存储,并送入GPU进行渲染.当然,这种做法在效率上来说是相当低下的,因为真正需要渲染的物体应该是视椎体内的物体 ...
- 文字识别的google的库 tesseract
https://github.com/tesseract-ocr/tesseract https://github.com/tesseract-ocr/tessdata 字体识 ...