Return Lua Tables from C++

Started by
11 comments, last by Matthew Shockley 13 years, 11 months ago
Let's say I have a function in C++: static int GetTable(lua_State* L) { return 1; } After I register this function, how can I make it return a Lua table? So when I call it returns a table like: {Name = "Bob", Age = 65, Gender = "African American"}
If I asked you for a hundred dollars would the answer to that question be the same as the answer to this question?
Advertisement
lua_newtable
lua_setfield

lua_newtable(L);lua_pushstring(L, "Bob");lua_setfield(L, -2, "Name");...
How do I return a userdata? Like if I had a userdata:

local u = newproxy(true)getmetatable(u).__index = GetValues(ud, ind)getmetatable(u).__newindex = GetNewValues(ud, ind, val)


How would I return this from a C++ function?
If I asked you for a hundred dollars would the answer to that question be the same as the answer to this question?
Pretty much the same thing. Lua doesn't care what's left on the stack at the end of the function, as it'll return it regardless of the type. Note that newproxy is undocumented and unsupported and may be removed or change in a future release, but it basically just creates a zero length user datum and attaches a metatable to it. Impossible to do from Lua, but trivial from C/C++.

//0 length user dataumlua_newuserdata(L, 0);//Create metatablelua_newtable(L);//Attach the metatable to the user datumlua_setmetable(L, -2);//Set fields...//user datum is on top the of the stack, return it to Luareturn 1;
By using the lua_setfield function? Can you give me some example code on how to set the fields? I am having problems with it. Sorry, but I am really new to the Lua API.
If I asked you for a hundred dollars would the answer to that question be the same as the answer to this question?
Can you tell me what I am doing wrong?

static int __index(lua_State* L) {	return 0;}static int __newindex(lua_State* L) {	return 0;}static int __tostring(lua_State* L) {	lua_pushstring(L, "Test");	return 1;}static int Object(lua_State* L) {	const char *val = lua_tostring(L, -1);	lua_pop(L, -1);	lua_newuserdata(L, 0);	lua_newtable(L);	lua_setmetatable(L, -2);	lua_pushcfunction(L, __index);	lua_setfield(L, -2, "__index");	lua_pushcfunction(L, __tostring);	lua_setfield(L, -2, "__tostring");	return 1;}static int print(lua_State* L) {	const char *mess = lua_tostring(L, -1);	Output(mess, 0, GetMainHWND());	return 0;}void CreateLuaFunctions(lua_State* L) {	lua_register(L, "print", print);	lua_register(L, "Object", Object);	//lua_register(L, "__index", __index);	//lua_register(L, "__newindex", __newindex);}


Thanks in advance. There is no errors, it just doesn't do anything.
If I asked you for a hundred dollars would the answer to that question be the same as the answer to this question?
I changed part of it to this:

static int Object(lua_State* L) {	const char *val = lua_tostring(L, -1);	lua_pop(L, -1);	lua_newtable(L);	lua_pushcfunction(L, __index);	lua_settable(L, -2);	lua_pushvalue(L, -1);	lua_setfield(L, -1, "__index");	lua_setmetatable(L, -1);	return 1;}


And now I am getting this Lua error:

attempt to index a function value

When I do this:

print(Object().Name)

If I asked you for a hundred dollars would the answer to that question be the same as the answer to this question?
Actually I get the same error when I do this:

local m = Object()
If I asked you for a hundred dollars would the answer to that question be the same as the answer to this question?
Quote:Original post by Matthew Shockley
Can you tell me what I am doing wrong?

*** Source Snippet Removed ***

Thanks in advance. There is no errors, it just doesn't do anything.


The problem with this is that when you setmetatable it pops the table from the stack. So you're setting the fields on the user datum, not on the metatable. You need to do a lua_pushvalue to copy the table to the top of the stack. The tricky part about the API is learning the visualize the Lua stack as you manipulate it. I'm actually surprised you didn't get an error by trying to set fields on user datum.


In your second example the line
lua_pushcfunction(L, __index);lua_settable(L, -2);

is the source of your error. lua_settable needs three operands, the index, value and the table. You only provide two, the table and value. Perhaps you meant to use setfield instead.
I changed it to this, but I am still getting the same error:

static int Object(lua_State* L) {	const char *val = lua_tostring(L, -1);	lua_pop(L, -1);	lua_newtable(L);	lua_pushcfunction(L, __index);	lua_setfield(L, -1, "__index");	lua_setmetatable(L, -2);	return 1;}
If I asked you for a hundred dollars would the answer to that question be the same as the answer to this question?

This topic is closed to new replies.

Advertisement