2017-09-03 83 views
2
的upvalue例如

让我们创建一个简单的C模块的Lua 5.3与全球intLua中共享使用C

static int l_test(lua_State *L){ 
    int Global = lua_tointeger(L, lua_upvalueindex(1)); 
    Global++; 
    lua_pushinteger(L, Global); 
    lua_pushvalue(L, -1); 
    lua_replace(L, lua_upvalueindex(1)); 
    //lua_pushnumber(L, Global); 
    return 1; 
} 

static int l_anotherTest(lua_State *L){ 
    int Global = lua_tointeger(L, lua_upvalueindex(1)); 
    Global++; 
    Global++; 
    lua_pushinteger(L, Global); 
    lua_pushvalue(L, -1); 
    lua_replace(L, lua_upvalueindex(1)); 
    //lua_pushnumber(L, Global); 
    return 1; 
} 

static const struct luaL_Reg testLib [] = { 
    {"test", l_test}, 
    {"anotherTest", l_anotherTest}, 
    {NULL, NULL} 
}; 

int luaopen_testLib(lua_State *L){ 
    luaL_newlibtable(L, testLib); 
    lua_pushinteger(L, 1); 
    luaL_setfuncs(L, testLib, 1) ;  
    return 1; 
} 

这几乎是工作,但是当我调用这两个函数从Lua是这样的:

local testLib = require "testLib" 
print(testLib.test()) 
print(testLib.anotherTest()) 

第二次打印应该是4,但它会打印出3。 我还在做什么错?

+1

要调用刚刚'setfuncs'之前初始化的upvalue,你应该推动其初始值压入堆栈。要从'l_test'访问upvalue,你应该使用'lua_upvalueindex(1)'来获得这个值所在的栈pseudoindex。 –

+0

感谢您的提示。我已经更新了这个问题。这里仍然缺少一些东西。你可以帮我吗? – user1511417

+0

如果您想要一个空指针常量,则使用'NULL'宏。使用整数'0'是一个令人迷惑的遗产。 – Olaf

回答

3

C封闭价值不分摊,只有Lua封闭价值上涨。每个C闭包都直接包含其upvalues(请参阅here)。如果要为两个或更多C关闭共享值,请使用一个公共表作为所有对象的upvalue,然后将共享值放在那里,或者将注册表用于共享数据。

类似下面应该做你想要什么:

#include <lua.h> 
#include <lauxlib.h> 


/* getint and setint may only be called from Lua C functions that 
* have the shared table as upvalue 1. 
*/ 

static int getint(lua_State *L){ 
    int v = 0; 
    lua_getfield(L, lua_upvalueindex(1), "myint"); 
    v = lua_tointeger(L, -1); 
    lua_pop(L, 1); /* remove integer from stack */ 
    return v; 
} 

static void setint(lua_State *L, int v){ 
    lua_pushinteger(L, v); 
    lua_setfield(L, lua_upvalueindex(1), "myint"); 
} 


static int l_test(lua_State *L){ 
    int Global = getint(L); 
    Global++; 
    setint(L, Global); 
    lua_pushinteger(L, Global); 
    return 1; 
} 

static int l_anotherTest(lua_State *L){ 
    int Global = getint(L); 
    Global++; 
    Global++; 
    setint(L, Global); 
    lua_pushinteger(L, Global); 
    return 1; 
} 

static const struct luaL_Reg testLib [] = { 
    {"test", l_test}, 
    {"anotherTest", l_anotherTest}, 
    {NULL, NULL} 
}; 

int luaopen_testLib(lua_State *L){ 
    luaL_newlibtable(L, testLib); 
    lua_newtable(L); 
    lua_pushinteger(L, 1); 
    lua_setfield(L, -2, "myint"); 
    luaL_setfuncs(L, testLib, 1); 
    return 1; 
} 
+0

@siffiejoe - 'luaL_setfuncs'允许您在所有注册的C函数中共享upvalues。这是OP试图实现的目标。 –

+2

@EgorSkriptunoff:来自luaL_setfuncs调用的所有C闭包在之后都具有相同的upvalues,但这些upvalues不是**共享的,即更改一个闭包的upvalues对其他闭包的upval没有影响,*除了*如果你改变通过引用传递的值,比如表,用户数据等(所有闭包都会对同一个表/ userdata/...有不同的引用)。 – siffiejoe

+1

我已经为您挖出了一个旧的邮件列表线程:http://lua-users.org/lists/lua-l/2006-08/msg00189.html – siffiejoe