lua - store closure in C, invoke async in C - c++

I need an idea, how I can store lua closures to invoke them asynchronously later.
my first idea was lua_tocfunction but a closure is not a cfunction and cannot be invoked from C directly
second idea was to save the closure in the metatable, that I can push it and call it later, but it seems, that I cannot copy a closure. (Error: attempt to index a function value).
So I need your help please. How can I store a closure?
I admit, that I did not completely understand why there is an __index field in my lua ctor as I've copied that part from somewhere.
By the way: the program without onrender worked as expected. I'm using qt gui and the lua-states are closed, after qt's main loop, thus the created window is not going to be delete by __gc after the script.
bootstrap.lua
local w = w_render() -- create window object
w:show()
w:onrender(function()
print('render')
end)
w_lua.cpp
// chlua_* are helper macros/templates/methods
// 1: self
// 2: render closure
int w_render_onrender(lua_State *L) {
auto *self = chlua_this<GLWindow *>(L, 1, w_render_table);
lua_pushvalue(L, 2); // copy closure to top
lua_setfield(L, 2, "onrender_cb"); // save closure in metatable
// !!! ERROR: attempt to index a function value
self->onrender([L](){
lua_getfield(L, 2, "onrender_cb");
qDebug() << "onrender";
lua_call(L, 0, 0);
});
return 0;
}
// Creates the object
int w_render(lua_State *L) {
auto *&self = chlua_newuserdata<GLWindow *>(L);
self = new GLWindow;
if (luaL_newmetatable(L, w_render_table)) {
luaL_setfuncs(L, w_render_methods, 0);
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
}
lua_setmetatable(L, -2);
return 1;
}

It looks like your problem is stemming from using the wrong indices and attempting to set/get fields on the wrong lua object on the stack. Assuming the udata representing your GLWindow * is first followed by the lua closure second, try changing the code like this:
int w_render_onrender(lua_State *L)
{
luaL_checkudata(L, 1, w_render_table);
luaL_checktype(L, 2, LUA_TFUNCTION);
auto *self = chlua_this<GLWindow *>(L, 1, w_render_table);
lua_getmetatable(L, 1);
lua_insert(L, -2); // GLWindow GLWindow_mt lua_closure
lua_setfield(L, -2, "onrender_cb"); // save closure in metatable
self->onrender([L]()
{
luaL_checkudata(L, 1, w_render_table);
// assuming GLWindow udata is self and onrender_cb is your lua closure above
// access GLWindow.onrender_cb through GLWindows's metatable
lua_getfield(L, 1, "onrender_cb");
qDebug() << "onrender";
luaL_checktype(L, -1, LUA_TFUNCTION); // Just to be sure
lua_call(L, 0, 0);
});
return 0;
}
Edit: After thinking about this some more, it probably makes more sense to create a lua reference using luaL_ref. This way you don't have to care what happens to be on the stack when self->onrender actually runs, which I'm assuming is async:
int w_render_onrender(lua_State *L)
{
luaL_checkudata(L, 1, w_render_table);
luaL_checktype(L, 2, LUA_TFUNCTION);
auto *self = chlua_this<GLWindow *>(L, 1, w_render_table);
auto lua_cb = luaL_ref(L, LUA_REGISTRYINDEX);
// just to check that what's on the stack shouldn't matter
lua_settop(L, 0);
self->onrender([L, lua_cb]()
{
lua_rawgeti(L, LUA_REGISTRYINDEX, lua_cb);
luaL_checktype(L, -1, LUA_TFUNCTION); // Just to be sure
qDebug() << "onrender";
lua_call(L, 0, 0);
luaL_unref(L, LUA_REGISTRYINDEX, lua_cb); // assuming you're done with it
});
return 0;
}

Related

Lua embedding in C++, how to handle uservalues

I am embedding Lua into a C++ application and would like to have a Lua table be associated with a C pointer.
In the object constructor I have:
Thing (const std::string name_, lua_State * L): name(name_)
{
std::string filename = name + ".lua";
luaL_dofile(L, filename.c_str());
lua_pushlightuserdata(L, this);
lua_newtable(L);
lua_setuservalue(L, 1); // Associate the Lua table with the userdata.
luaL_getmetatable(L, "Metatable.Thing");
lua_setmetatable(L, 1);
}
In the __newindex metamethod of the "Metatable.Thing" metatable I have:
static int ThingNewIndex(lua_State * L)
{
assert(lua_isuserdata(L, 1));
assert(lua_isstring(L, 2));
Thing * thing = (Thing *)lua_touserdata(L, 1);
const char * index = lua_tostring(L, 2);
lua_getuservalue(L, 1);
assert(lua_istable(L, -1)); // This assertion fails.
lua_pushvalue(L, 2);
lua_pushvalue(L, 3);
lua_settable(L, -3);
return 0;
}
The lua_getuservalue function does not put any table onto the stack.
Am I misunderstanding something about how user values work? Is there another way to associate a C++ pointer with a Lua table?

Lua 5.2 Sandboxing in different objects with C API

Consider the following C++ code using the Lua C API:
#include <string>
#include <cassert>
#include <lua/lua.hpp>
class AwesomeThing
{
lua_State* _lua;
std::string _name;
public:
AwesomeThing(lua_State* L, const std::string& name, const std::string& luafile)
: _lua{ L },
_name{ name }
{
assert(luaL_loadfile(_lua, luafile.c_str()) == 0); // 1:chunk
lua_newtable(_lua); // 1:chunk, 2:tbl
lua_newtable(_lua); // 1:chunk, 2:tbl, 3:tbl(mt)
lua_getglobal(_lua, "_G"); // 1:chunk, 2: tbl, 3:tbl(mt), 4:_G
lua_setfield(_lua, 3, "__index"); // 1:chunk, 2: tbl, 3:tbl(mt)
lua_setmetatable(_lua, 2); // 1:chunk, 2: tbl
lua_setupvalue(_lua, -2, 1); // 1:chunk
if (lua_pcall(_lua, 0, 0, 0) != 0) // compiled chunk
{
auto error = lua_tostring(_lua, -1);
throw std::runtime_error(error);
}
lua_setglobal(_lua, _name.c_str()); // empty stack
}
void init()
{
lua_getglobal(_lua, _name.c_str()); // 1:env
assert(lua_isnil(_lua, 1) == 0);
lua_getfield(_lua, 1, "onInit"); // 1:env, 2:func
assert(lua_isnil(_lua, 2) == 0);
assert(lua_isfunction(_lua, 2) == 1);
assert(lua_pcall(_lua, 0, LUA_MULTRET, 0) == 0); // 1:env, 2:retval
lua_pop(_lua, 1); // -1:env
lua_pop(_lua, 1); // empty stack
assert(lua_gettop(_lua) == 0);
}
};
int main()
{
lua_State* L = luaL_newstate();
luaL_openlibs(L);
AwesomeThing at1(L, "thing1", "file1.lua");
AwesomeThing at2(L, "thing2", "file2.lua");
at1.init();
at2.init();
return 0;
}
With two very basic Lua files:
file1.lua
function onInit()
print("init file1")
end
file2.lua
function onInit()
print("init file2")
end
As is, I get an error in at2's constructor call at lua_pcall: attempt to call table value
When I comment out all references/calls to at2, I instead get an error in at1's init() at lua_getfield(_lua, 1, "onInit"): PANIC: unprotected error in call to Lua API (attempt to index a nil value)
I feel like there's something fundamental I'm missing in the way I'm handling the sandboxing. I've tried my best to follow a few other Lua 5.2 sandboxing examples I've found online, but so far nothing has helped.
After messing around with the code myself, I was able to fix it and the errors seem to come from just a few errors.
lua_pcall pops the called function from the stack, but in both cases in your code you assume the function is still on the stack after lua_pcall. This results in bad stack manipulation.
In the constructor, you apparently try to store a reference to the chunk (function) instead of the environment table. This doesn't even work though, because the function was already popped. If it did work, the lua_getfield call in init() wouldn't work as intended since the chunk doesn't have a field named onInit -- the environment table does.
Fixing the constructor involves creating the environment table and loading the chunk in the opposite order, so that the environment table is left on the stack after the function call:
lua_newtable(_lua); // 1:tbl
assert(luaL_loadfile(_lua, luafile.c_str()) == 0); // 1:tbl, 2:chunk
lua_newtable(_lua); // 1:tbl, 2:chunk, 3:tbl(mt)
lua_getglobal(_lua, "_G"); // 1:tbl, 2:chunk, 3:tbl(mt), 4:_G
lua_setfield(_lua, 3, "__index"); // 1:tbl, 2:chunk, 3:tbl(mt)
lua_setmetatable(_lua, 1); // 1:tbl, 2:chunk
lua_pushvalue(_lua, 1); // 1:tbl, 2:chunk, 3:tbl
lua_setupvalue(_lua, -2, 1); // 1:tbl, 2:chunk
if (lua_pcall(_lua, 0, 0, 0) != 0) // compiled chunk
{
auto error = lua_tostring(_lua, -1);
throw std::runtime_error(error);
}
// 1:tbl
lua_setglobal(_lua, _name.c_str()); // empty stack
Then in init(), since you use LUA_MULTRET, just clear the stack by replacing both pop calls with lua_settop(_lua, 0).

Lua Array and Object Oriented Access for the Same Userdata

I have an CArray class written in C++ and is exposed to Lua as Array.
1) Create a new userdata:
int Array_new(lua_State* L)
{
int len = luaL_checkint(L, 1);
CArray<std::string> **Arr = (CArray<std::string>**)lua_newuserdata(L, sizeof(CArray<std::string>*));
*Arr = new CArray<std::string>(len);
luaL_getmetatable(L, "ArrayMetatable");
lua_setmetatable(L, -2);
return 1;
}
2) Access an element:
int Array_getValue(lua_State* L)
{
CArray<std::string>* arr = *(CArray<std::string>**)lua_touserdata(L, 1);
int pos=luaL_checknumber(L, 2)-1;
//Omitted for brevity
lua_pushstring(L, stdStr.c_str());
return 1;
}
3) Register to Lua:
int luaopen_Array(lua_State* L)
{
luaL_newmetatable(L, "ArrayMetatable"); // metatable1
luaL_setfuncs(L, Array_metatable, 0);
lua_pushstring(L, "__index");
lua_pushvalue(L, -2); // metatable1 __index metatable1
lua_settable(L, -3); // metatable1[__index]=metatable1
/*luaL_newmetatable(L, "ArrayMetatable_2"); // metatable1 metatable2
lua_pushstring(L, "__index"); // metatable1 metatable2 __index
lua_pushstring(L, "get"); // metatable1 metatable2 __index get
lua_gettable(L, 1); // metatable1 metatable2 __index
lua_settable(L, 2);
lua_pushvalue(L, 1); //metatable1 metatable2 metatable1*/
lua_setglobal(L, "Array");
return 0;
}
The problem is I have to prefer either Lua code to access an element in the array: a) arr:get(1) to get the first element, b) arr[1] to get the first element.
However a and b does not work at the same time, so either I have to prefer style a or style b. Is it possible to do a and b at the same time by modifying the 3rd step?
So far the code I presented gives an error at step 2 if I try a Lua expression such as arr[2] such that the variable arr's address is 0xcccccc.
You can add an __index method and a get method, just add them separately.
The registration function looks a little messed up.
Normally you would have two meta-tables - the global functions, and the member functions.
static const struct luaL_Reg Array_globals[] = {
{ "new", Array_new },
{ NULL,NULL }
};
static const struct luaL_Reg Array_members[] = {
{ "get", Array_getValue},
{ "__index", Array_getValue },
{ NULL,NULL }
};
the luaopen_ function merely needs to build the tables with the appropriate methods.
I would recommend also writing __len, and __setindex
int luaopen_Array(lua_State* L)
{
luaL_newmetatable(L, "ArrayMetatable"); // metatable1
luaL_setfuncs(L, Array_members, 0);
luaL_newlib( L, Array_globals );
return 1; // return table to caller.
}

Creating new classes/members at run-time in scripting languages used in C++ [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
I've been working on this problem off and on for a few months, and now wanted to really come up with a proper solution that will handle the case of creating new user-defined classes (and instances of those classes) with member functions/properties at run-time in a C++11 project.
So far, I've been using SWIG (formerly with Python, now with Lua, exploring Squirrel). Like all the C++ binding/embedding libraries I've encountered so far (Luna*, luabinder, luabind, OOLua, Sqrat/Sqext, Squall), all expect your classes to be predefined in C++ prior to code execution because they either rely on preprocessor directives or templates.
So my question is, are there any libraries out there that use a more procedural approach to wrapping a language, or are there any good tutorials/examples for something like Lua or Squirrel, that one would recommend for handling the creation of custom-named classes with custom members and functions? Some direction would be greatly appreciated.
Even simply a good example showing how to create a custom class with a function and a property, in either Lua, Squirrel, via their respective C++ APIs without the use of macros/templates/dynamically-generated code, would be hugely helpful.
EDIT: I have gone as far as creating an Instance class that contains a std::vector of members key/value pairs, and a member identifying the type so functions can be looked up. However, there is very little documentation out there on creating simple classes in Lua/Squirrel without the use of static code.
EDIT 2: I would like a solution that works on any platform and without having to dynamically link.
Creating a class derived from some existing C++ class is the only way (known to me) to bring a new class into a running C++ program. Short of dynamically compiling actual C++ source and loading the resulting library, there is no way to physically add a new class. The next best thing is to create a proxy object in C++ that wraps a Python (Lua etc) object, and make that Python (Lua) object an instance of a class that extends an existing C++ class mirrored to the Python (Lua) side.
C++
+---------+ mirrors +--------------+
| class X | ...............................> | class X |
+---------+ | mirrored to |
| | Python |
| inherits +--------------+
v inherits |
+-----------------+ v
| class X_Wrapper | references +--------------+
| | python obj -------------------------> | class CX(X): |
+-----------------+ | def met() |
+--------------+
Here's an example of extending a C++ class with Python, using boost::python as a bridge.
C++ side:
#include <boost/python.hpp>
#include <iostream>
using namespace boost::python;
// this is the interface we will implement in Python
struct World
{
virtual std::string greet() = 0;
virtual ~World() {}
};
// this is a helper class needed to access Python-overrided methods
struct WorldWrap : World, wrapper<World>
{
std::string greet()
{
return this->get_override("greet")();
}
};
// This function tests our class implemented in Python
std::string test(World* w)
{
std::cout << "Calling w->greet() on some World-derived object\n";
return w->greet();
}
// This is what the Python side will see
BOOST_PYTHON_MODULE(hello)
{
class_<WorldWrap, boost::noncopyable>("World")
.def("greet", pure_virtual(&World::greet));
def("test", test);
}
Python side:
import hello
class HomeWorld(hello.World):
""" Implements a function defined in C++ as pure virtual """
def greet(self):
return "howdy"
home = HomeWorld()
print (hello.test(home))
Consider following Lua multimap example.
Multimap = {};
function Multimap:__index(key)
if (key == 'keys') then
local ret = {}
for k,_ in pairs(self) do
ret[#ret+1] = k;
end
return ret;
else
return rawget(getmetatable(self), key)
end
end
function Multimap.Create()
local self = {};
setmetatable(self, Multimap);
return self;
end
function Multimap:Insert(key, value)
local list = self[key];
if (list == nil) then
list = {};
self[key] = list;
end
table.insert(list, value);
end
function Multimap:Remove(key, value)
local list = self[key];
assert(list ~= nil, "key not found");
for i = 1,#list do
if (list[i] == value) then
table.remove(list, i);
if (#list == 0) then
self[key] = nil;
end
return;
end
end
error("value not found");
end
-- testing
m = Multimap.Create()
m:Insert(1,5)
m:Insert(2,6)
m:Insert(3,7)
m:Insert(1,8)
m:Remove(2,6)
print(pcall(function()
m:Remove(2,6) -- will produce assert exception
end))
print("keys left: ", table.concat(m.keys, ','))
You can implement this in C++ in several ways.
Use heavy Lua API. The code below is almost exact to Lua.
#include <Lua/src/lua.hpp>
int Multimap_Index(lua_State* L) {
lua_settop(L, 2); // force 2 arguments
const char *key_value = "key";
size_t key_len;
const char *key = lua_tolstring(L, 2, &key_len);
if (!strncmp(key, key_value, strlen(key_value))) {
int i = 0;
lua_newtable(L); // stack : self, key, ret = {}
int ret = lua_gettop(L);
lua_pushnil(L); // stack : self, key, ret, nil
while (lua_next(L, 1) != 0) { // stack : self, key, ret, k, v
lua_pop(L, 1); // stack : self, key, ret, k
lua_len(L, ret); // stack : self, key, ret, k, #ret
lua_pushvalue(L, -2); // stack : self, key, ret, k, #ret, k
lua_rawseti(L, ret, lua_tointeger(L, -2)+1); // ret[#ret+1] = k ; || stack : self, key, ret, k, #ret
lua_pop(L, 1); // stack : self, key, ret, k
}
// stack : self, key, ret
return 1;
}
else {
lua_getmetatable(L, 1); // stack : self, key, metatable(self)
lua_pushvalue(L, 2); // stack : self, key, metatable(self), key
lua_rawget(L, -2); // stack : self, key, metatable(self), rawget(metatable(self), key)
return 1;
}
}
int Multimap_Remove(lua_State* L) {
lua_settop(L, 3); // force 3 arguments: self, key, value
lua_checkstack(L, 12); // reserve 12 arguments on stack (just in case)
lua_pushvalue(L, 2); // stack: self, key, value, key
lua_gettable(L, 1); // stack: self, key, value, list = self[key]
if (lua_isnil(L, -1))
luaL_error(L, "key not found");
lua_len(L, -1); // stack: self, key, value, list, #list
int count = lua_tointeger(L, -1);
lua_pop(L, 1); // stack: self, key, value, list
for (int i = 1; i <= count; ++i) {
lua_rawgeti(L, -1, i); // stack: self, key, value, list, v = list[i]
if (lua_compare(L, 3, 5, LUA_OPEQ)) { // if (list[i] == value)
lua_getglobal(L, "table"); // stack : self, key, value, list, v, table
lua_getfield(L, -1, "remove"); // stack : self, key, value, list, v, table, table.remove
lua_pushvalue(L, 4);
lua_pushinteger(L, i); // stack : self, key, value, list, v, table, table.remove, list, i
lua_call(L, 2, 0); // table.remove(list, i); || stack : self, key, value, list, v, table
lua_pushnil(L);
if (lua_next(L, 4) == 0) { // if list is empty table
lua_pushvalue(L, 2);
lua_pushnil(L);
lua_settable(L, 1); // self[key] = nil
}
return 0;
}
}
luaL_error(L, "value not found");
}
int main() {
auto L = luaL_newstate();
luaL_openlibs(L);
lua_newtable(L);
int Multimap = lua_gettop(L); // Multimap = {}
lua_pushvalue(L, Multimap);
lua_setglobal(L, "Multimap"); // _G.Multimap = Multimap;
// option 1: create a C function for operation
// Multimap.__index = &Multimap_Index
lua_pushcfunction(L, Multimap_Index);
lua_setfield(L, Multimap, "__index");
// option 2: compile Lua code and use it
luaL_loadstring(L,
"local self = {};\n"
"setmetatable(self, Multimap);\n"
"return self;\n"
);
lua_setfield(L, Multimap, "Create"); // Multimap.Create = &Multimap_Create
luaL_loadstring(L,
"local self, key, value = ...;\n" // initialize local variables from parameters here
"local list = self[key];\n"
"if (list == nil) then\n"
" list = {};\n"
" self[key] = list;\n"
"end\n"
"table.insert(list, value);\n"
);
lua_setfield(L, Multimap, "Insert"); // Multimap.Create = &Multimap_Insert
lua_pushcfunction(L, Multimap_Remove);
lua_setfield(L, Multimap, "Remove"); // Multimap.Create = &Multimap_Remove
lua_getfield(L, Multimap, "Create");
lua_call(L, 0, 1);
int m = lua_gettop(L);
lua_getfield(L, m, "Insert"); // stack : m, m.insert
int Insert = lua_gettop(L);
// m.Insert(m, 1, 5)
lua_pushvalue(L, Insert);
lua_pushvalue(L, m);
lua_pushinteger(L, 1);
lua_pushinteger(L, 5);
lua_call(L, 3, 0);
// m.Insert(m, 2, 6)
lua_pushvalue(L, Insert);
lua_pushvalue(L, m);
lua_pushinteger(L, 2);
lua_pushinteger(L, 6);
lua_call(L, 3, 0);
// m.Insert(m, 3, 7)
lua_pushvalue(L, Insert);
lua_pushvalue(L, m);
lua_pushinteger(L, 3);
lua_pushinteger(L, 7);
lua_call(L, 3, 0);
// m.Insert(m, 1, 8)
lua_pushvalue(L, Insert);
lua_pushvalue(L, m);
lua_pushinteger(L, 1);
lua_pushinteger(L, 8);
lua_call(L, 3, 0);
// m.Remove(m, 2, 6)
lua_getfield(L, m, "Remove");
lua_pushvalue(L, m);
lua_pushinteger(L, 2);
lua_pushinteger(L, 6);
lua_call(L, 3, 0);
// m.Remove(m, 2, 6)
lua_getfield(L, m, "Remove");
lua_pushvalue(L, m);
lua_pushinteger(L, 2);
lua_pushinteger(L, 6);
lua_pcall(L, 3, 0, 0);
printf("%s\n", lua_tostring(L, -1));
lua_getglobal(L, "table");
lua_getfield(L, -1, "concat");
lua_getfield(L, m, "keys");
lua_pushstring(L, ",");
lua_call(L, 2, 1);
printf("keys left: %s\n", lua_tostring(L, -1));
lua_close(L);
return 0;
}
OR you can use Lua userdata that uses std::multimap (I would need another hour to implement this, so ask if you really need that -- that doesn't follow from your question)
Disclaimer: I'm posting this contribution as an answer because I don't have enough reputation points to add a comment.
Comment: Setting aside the problematic of binding with a specific scripting language, it seems that you are facing a fundamental limitation of the C++ language: it is not "dynamic" (as pointed out by other comments). That is, the language does not provide any functionality to extend or modify a compiled program.
Maybe all hope is not lost, though. Searching the web for "c++ dynamic loading" reveals that some systems (such and Linux and Windows) do seem to implement a dynamic loading mechanism.
Here are the links to two (old) articles that talk about the subject.
Dynamic Class Loading for C++ on Linux in the Linux Journal.
Dynamically Loaded C++ Objects in Dr.Dobb's.
They seem interesting at first glance. I'm not sure they are still relevant, though.
This is but a shot in the dark.

Calling a lua function from table.subtable in C++

im trying to call a lua function from C++ where function is in subtable of global table. Im using lua version 5.2.* compiled from source.
Lua function
function globaltable.subtable.hello()
-- do stuff here
end
C++ code
lua_getglobal(L, "globaltable");
lua_getfield(L, -1, "subtable");
lua_getfield(L, -1, "hello");
if(!lua_isfunction(L,-1)) return;
lua_pushnumber(L, x);
lua_pushnumber(L, y);
lua_call(L, 2, 0);
However im unable to call it, i always get an error
PANIC: unprotected error in call to Lua API (attempt to index a nil value)
On line #3: lua_getfield(L, -1, "hello");
What am I missing?
Side question: I would love to know also how to call function deeper than this - like globaltable.subtable.subsubtable.hello() etc.
Thank you!
This is what im using to create the globaltable:
int lib_id;
lua_createtable(L, 0, 0);
lib_id = lua_gettop(L);
luaL_newmetatable(L, "globaltable");
lua_setmetatable(L, lib_id);
lua_setglobal(L, "globaltable");
how do i create the globaltable.subtable?
function is a keyword in Lua, I am guessing on how did you manage to compile the code:
-- test.lua
globaltable = { subtable = {} }
function globaltable.subtable.function()
end
When this is run:
$ lua test.lua
lua: test.lua:2: '<name>' expected near 'function'
Maybe you changed the identifiers for this online presentation, but check that on line 2 "subtable" really exists in the globaltable, because on line 3, the top of stack is already nil.
Update:
To create multiple levels of tables, you can use this approach:
lua_createtable(L,0,0); // the globaltable
lua_createtable(L,0,0); // the subtable
lua_pushcfunction(L, somefunction);
lua_setfield(L, -2, "somefunction"); // set subtable.somefunction
lua_setfield(L, -2, "subtable"); // set globaltable.subtable
lua_newtable(L);
luaL_newmetatable(L, "globaltable");
lua_newtable(L); //Create table
lua_setfield(L, -2, "subtable"); //Set table as field of "globaltable"
lua_setglobal(L, "globaltable");
This is what i was looking for.