2015-09-24 62 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; 
} 

這是不是很優雅但是,考慮到它使用一個共享的註冊表,這可能是在會議期間加載的其他圖書館可以訪問,所以我仍然樂意提供更好的選擇。