缘起

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
注意事项
  1. test.lua 和 mytest.so放在同一个目录.
  2. 如果编译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的用法示例的更多相关文章

  1. python中的随机函数random的用法示例

    python中的随机函数random的用法示例 一.random模块简介 Python标准库中的random函数,可以生成随机浮点数.整数.字符串,甚至帮助你随机选择列表序列中的一个元素,打乱一组数据 ...

  2. STL中map,set的基本用法示例

    本文主要是使用了STL中德map和set两个容器,使用了它们本身的一些功能函数(包括迭代器),介绍了它们的基本使用方式,是一个使用熟悉的过程. map的基本使用: #include "std ...

  3. 用 SwitchHosts设置hotst, 用法示例

    涉及到本地默认ip(localhost,127.0.0.1)设置关联地址时,使用XAMPP本地服务器时避免自动跳转设置的域名的一些处理方法 打开此文件,把内容修改如下 # Virtual Hosts# ...

  4. 标准C++中的string类的用法总结

    标准C++中的string类的用法总结 相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的确,MFC中的CString类使用起来真的非常的方便好用.但是如果离开了MFC框架,还有 ...

  5. 【转】java.util.vector中的vector的详细用法

    [转]java.util.vector中的vector的详细用法 ArrayList会比Vector快,他是非同步的,如果设计涉及到多线程,还是用Vector比较好一些 import java.uti ...

  6. jquery中attr()与prop()函数用法实例详解(附用法区别)

    本文实例讲述了jQuery中attr()与prop()函数用法.分享给大家供大家参考,具体如下: 一.jQuery的attr()方法 jquery中用attr()方法来获取和设置元素属性,attr是a ...

  7. oracle中to_date详细用法示例(oracle日期格式转换)

    这篇文章主要介绍了oracle中to_date详细用法示例,包括期和字符转换函数用法.字符串和时间互转.求某天是星期几.两个日期间的天数.月份差等用法 TO_DATE格式(以时间:2007-11-02 ...

  8. .NET中代理服务器WebProxy的各种用法

    引用地址 引用 因为涉及到代理的各种情况,WebRequest和WebProxy类的文档写的相当复杂,不但各个文档关注点不同,而且不同版本的同一文档也有小小的区别,网上也没有关于这个类的相关文章.于是 ...

  9. Vue基础01vue的基本示例,vue的双向数据绑定,vue中常见的几种用法,vue相关常见指令

    自学vue框架,每天记录重要的知识点,与大家分享!有不足之处,希望大家指正. 本篇将讲述:vue的基本示例,vue的双向数据绑定,vue中常见的几种用法,vue相关常见指令 前期学习基础,使用vue. ...

随机推荐

  1. java通过ping 判断网络是否正常

    import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.i ...

  2. ambari安装集群下python连接hbase之安装thrift

    简介: python连接hbase是需要通过thrift连进行连接的,ambari安装的服务中貌似没有自带安装hbase的thrift,我是看配置hbase的配置名称里面没有thrift,cdh版本的 ...

  3. HDU_5514_Frogs

    Frogs Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  4. 关于ios7 UINavigationController.interactivePopGestureRecognizer手势集成

    因为公司业务需求,结合网上的资料整理了一下. 如果自定义过navbar的leftbarbutton 或者backbarbutton 原生interactivePopGestureRecognizer默 ...

  5. python 时间与时间戳之间的转换

    https://blog.csdn.net/kl28978113/article/details/79271518 对于时间数据,如2016-05-05 20:28:54,有时需要与时间戳进行相互的运 ...

  6. Redis常见操作

    1. 对于key的所有操作 del key1 key2 … keyn 作用:删除1个或者多个键返回值:不存在的key忽略掉,返回真正删除的key的数量 rename key newkey 作用:给ke ...

  7. 【我的Android进阶之旅】推荐一款视频转换GIF图片格式的转换工具(Video to GIF)

    一.背景 最近想把一些Android Demo的运行效果图获取下来,但是一直使用真机进行调试,在电脑上不好截取一段gif动画.而之前使用模拟器的时候可以使用 GifCam 工具进行屏幕动画截取.Gif ...

  8. SQL Server扩展事件-- 使用system_health默认跟踪会话监控死锁

    SQL Server扩展事件(Extended Events)-- 使用system_health默认跟踪会话监控死锁 转自:http://blog.51cto.com/ultrasql/160037 ...

  9. Mac 升级 OpenSSL

    [转载自 https://blog.csdn.net/focusjava/article/details/51179297 ] [升级Mac的openssl] 终端下 openssl version ...

  10. PAT 1086 Tree Traversals Again[中序转后序][难]

    1086 Tree Traversals Again(25 分) An inorder binary tree traversal can be implemented in a non-recurs ...