Reputation: 1389
I am trying to wrap ncurses in Lua using the C API. I am working with the stdscr
pointer: This is NULL before initscr
is called, and initscr
is called from Lua by design of my bindings. So in the driver function I do this:
// Driver function
LUALIB_API int luaopen_liblncurses(lua_State* L){
luaL_newlib(L, lncurseslib);
// This will start off as NULL
lua_pushlightuserdata(L, stdscr);
lua_setfield(L, -2, "stdscr");
lua_pushstring(L, VERSION);
lua_setglobal(L, "_LNCURSES_VERSION");
return 1;
}
This works as intended. The trouble comes when I need to modify stdscr
. initscr
is bound like this:
/*
** Put the terminal in curses mode
*/
static int lncurses_initscr(lua_State* L){
initscr();
return 0;
}
I need to moify the stdscr
in the library to no longer be null. Example code from Lua side:
lncurses = require("liblncurses");
lncurses.initscr();
lncurses.keypad(lncurses.stdscr, true);
lncurses.getch();
lncurses.endwin();
But, lncurses.stdscr
is NULL, so the it's essentially running the c equivalent of keypad(NULL, true);
My question being, how do I modify library values in Lua after the library is created?
Upvotes: 2
Views: 330
Reputation: 3103
You can use the registry.
Lua provides a registry, a predefined table that can be used by any C code to store whatever Lua values it needs to store. The registry table is always located at pseudo-index
LUA_REGISTRYINDEX
. Any C library can store data into this table, but it must take care to choose keys that are different from those used by other libraries, to avoid collisions. Typically, you should use as key a string containing your library name, or a light userdata with the address of a C object in your code, or any Lua object created by your code. As with variable names, string keys starting with an underscore followed by uppercase letters are reserved for Lua.
Store a reference to the module table in the registry on creation.
LUALIB_API int luaopen_liblncurses(lua_State* L) {
luaL_newlib(L, lncurseslib);
// This will start off as NULL
lua_pushlightuserdata(L, stdscr);
lua_setfield(L, -2, "stdscr");
lua_pushstring(L, VERSION);
lua_setglobal(L, "_LNCURSES_VERSION");
// Create a reference to the module table in the registry
lua_pushvalue(L, -1);
lua_setfield(L, LUA_REGISTRYINDEX, "lncurses");
return 1;
}
Then when you initscr
, update the field.
static int lncurses_initscr(lua_State* L) {
initscr();
// Update "stdscr" in the module table
lua_getfield(L, LUA_REGISTRYINDEX, "lncurses");
lua_pushlightuserdata(L, stdscr);
lua_setfield(L, -2, "stdscr");
return 0;
}
Upvotes: 1