2015-09-24 20 views
4

当我将Lua整合到我的C程序中时,我一直在使用指向C结构的指针来存储我需要在与Lua绑定的方法中重用的对象州。在Lua注册表中存储C结构

但是,一旦我从主程序中分离出我的Lua库文件,这就不起作用,所以它似乎需要使用注册表来存储我的结构。

我该如何去存储我的C结构指针在Lua注册表中?

这是目前我在做什么:

static augeas *aug = NULL; 


static int lua_aug_get(lua_State *L) { 
    // Use aug to do something here 
    /* return the number of results */ 
    return 1; 
} 

struct lua_State *luaopen_augeas(augeas *a) { 
    lua_State *L = luaL_newstate(); 
    aug = a; // this clearly does not work 
    luaL_openlibs(L); 
    // The methods below will need to access the augeas * struct 
    // so I need to push it to the registry (I guess) 
    static const luaL_Reg augfuncs[] = { 
     { "get", lua_aug_get }, 
     { "label", lua_aug_label }, 
     { "set", lua_aug_set }, 
     { NULL, NULL } 
    }; 

    luaL_newlib(L, augfuncs); 
    lua_setglobal(L, "aug"); 

    return L; 
} 

编辑:从答案,我在IRC上了,看来我应该使用metatable,所以我目前正在研究这个。

回答

3

如果注册表不是用于存放指向安全,不够到位,你可以把它作为一个的upvalue到具体功能:

static int lua_aug_get(lua_State *L) { 
    augeas *aug = lua_touserdata(L, lua_upvalueindex(1)); 
    // Do stuff with aug 
    return 1; 
} 

static const luaL_Reg augfuncs[] = { 
    { "get", lua_aug_get }, 
    { "label", lua_aug_label }, 
    { "set", lua_aug_set }, 
    { NULL, NULL } 
}; 
lua_createtable(L, 0, 0); 
for (size_t i = 0; augfuncs[i].name; i++) { 
    lua_pushlightuserdata(L, a); 
    lua_pushcclosure(L, augfuncs[i].func, 1); 
    lua_setfield(L, -2, augfuncs[i].name); 
} 

但它是好的,将其存储在注册表中。它不是脚本可访问的,除了debug库之外,通常不会在沙箱中暴露。如果其他图书馆在那里造成自私的混乱,无论如何你都会遇到麻烦。

1

我设法得到它使用一个Lua注册表指数和推动指针用户数据的工作:

static const char *Key = "augeas_registry_key"; // The registry key 

static augeas *checkaug(lua_State *L) { 
    lua_pushlightuserdata(L, (void *)&Key);  // set the registry key 
    lua_gettable(L, LUA_REGISTRYINDEX);   // retrieve value 
    augeas *aug = (augeas *)lua_touserdata(L, -1); // cast value 
    return aug; 
} 

static int lua_aug_get(lua_State *L) { 
    augeas *aug = checkaug(L); 
    // Do stuff with aug 
    return 1; 
} 

struct lua_State *luaopen_augeas(augeas *a) { 
    lua_State *L = luaL_newstate(); 
    luaL_openlibs(L); 

    lua_pushlightuserdata(L, (void *)&Key); // set registry key 
    lua_pushlightuserdata(L, (void *)a); // push pointer 
    lua_settable(L, LUA_REGISTRYINDEX);  // push to in registry 

    static const luaL_Reg augfuncs[] = { 
     { "get", lua_aug_get }, 
     { "label", lua_aug_label }, 
     { "set", lua_aug_set }, 
     { NULL, NULL } 
    }; 

    luaL_newlib(L, augfuncs); 
    lua_setglobal(L, "aug"); 

    return L; 
} 

这是不是很优雅但是,考虑到它使用一个共享的注册表,这可能是在会议期间加载的其他图书馆可以访问,所以我仍然乐意提供更好的选择。