lua5.3中luaL_setfunc设置upvalue的用法示例

https://www.cnblogs.com/cheerupforyou/p/7192307.html

缘起

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的作用.

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • lua是一门语法简单,效率很高的脚本语言,能够很方便的与C语言交互,很适合做胶水语言使用,本文内容有两部分,...
    小灰_06e4阅读 3,322评论 0 1
  • LUA调用C库和闭包(OpenWrt中UCI-LUA的学习) 不是为了学习UCI, 而是学习UCI中C代码和LUA...
    突击手平头哥阅读 1,177评论 0 0
  • 第一篇 语言 第0章 序言 Lua仅让你用少量的代码解决关键问题。 Lua所提供的机制是C不擅长的:高级语言,动态...
    testfor阅读 2,770评论 1 7
  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 14,029评论 0 38
  • 1.Lua 交互式编程 and 脚本式编程2.注释单行:--多行:--[[ --]] 多行推荐使...
    只猿阅读 568评论 0 1