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
注意事項
  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的作用.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM