Jump to content
  • Advertisement
Sign in to follow this  
Matthew Shockley

Return Lua Tables from C++

This topic is 3004 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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"}

Share this post


Link to post
Share on other sites
Advertisement
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?

Share this post


Link to post
Share on other sites
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 dataum
lua_newuserdata(L, 0);
//Create metatable
lua_newtable(L);
//Attach the metatable to the user datum
lua_setmetable(L, -2);

//Set fields
...
//user datum is on top the of the stack, return it to Lua
return 1;

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!