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

缘起

luaL_setfuncs 这个函数能够注册c函数到lua,另外还能够设置闭包函数使用的变量upvalue. 我没有用过,在 云风的skynet 才第一次见过,因而写个例子实际使用如下.linux

函数原型:

void luaL_setfuncs (lua_State L, const luaL_Reg l, int nup);centos

文档定义:

Registers all functions in the array l (see luaL_Reg) into the table on the top of the stack (below optional upvalues, see next).api

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源码并编译ui

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.solua

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的做用.centos7

相关文章
相关标签/搜索