Sign in to follow this  

Return Lua Tables from C++

This topic is 2782 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

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

This topic is 2782 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.

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