Sign in to follow this  
Matthew Shockley

Return Lua Tables from C++

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
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
m_switch    234
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
m_switch    234
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
m_switch    234
I'm not in a location where I can test the code.

There's a couple questionable things I see however. lua_pop pops n elements from the stack, a negative number does not make sense here. You setmetatable at the end, but it's unclear what you're trying to set the metatable on. If you're calling Object without any parameters then there's nothing to set the table on, and might be the source of your error.

Share this post


Link to post
Share on other sites
I don't know how to code this. Maybe you can help me. When the Lua script calls the function,"Object", I want the function to return a userdata with the __index metamethod calling a C++ function named __index. Please help me.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this