[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: Replaced print function return stack getting emptied
- From: Bruce Wheaton <bruce@...>
- Date: Sun, 6 May 2012 21:01:51 -0700
On May 6, 2012, at 1:37 PM, Steven Johnson wrote:
>> I'm confused then. My loadString chunk is, for instance: print ("hello")
>> If I enter: return ("hello") then the stack does have a string - hello on it.
>> How do I call a C function and get return results if that doesn't work?
> It isn't that you're not getting results, they just aren't going anywhere. :)
> The chunk is itself a Lua function (thus the pcall()), so you return
> values from it
> like any other. Thus a return ("hello") works, but not a naked print().
It's not a naked print, it's a replaced print that also returns things on the stack.
>> As a workaround, I see what you mean. But not being able to get return values is confusing me. It feels like I'm doing something wrong. If 'return "hello"' works, it feels like a C function that returns values should too.
> It wasn't even a workaround, really. Once you go beyond simple
> one-liners (e.g. two print() statements in a row), you'd end up
> needing something similar, most likely. Perhaps something like this
Ah ha. You are correct. So although I'm still confused as to why I don't get anything on the stack (I thought that was the point of it), in the case of print, you're completely right. I was so focussed on the test aspect - a chunk with one print statement, I forgot the real world situation, which is arbitrary user code scattered with prints. So my C print override has to, like you say, make a table or pass the strings back for printing. Thanks for that!
Thanks for the table snippets - I'll try to get my head around that. I think I see what's going on - making a table to hold the results, then retrieving it.
> // Before your loadstring / pcall
> lua_setglobal(luaVM, "MyTable");
> // Somewhere near the end of print()
> lua_getglobal(luaVM, "MyTable"); // items, table
> if (!lua_isnil(luaVM, -1))
> int base = -nreturns - 1;
> for (int i = 0; i < nreturns; ++i)
> lua_pushvalue(luaVM, base + i); // items, table, items[i + 1]
> lua_rawseti(luaVM, -2, i + 1); // items, table
> lua_pushinteger(luaVM, nreturns); // Save number of items (there may be nils)
> lua_setfield(luaVM, -1, "n");
> lua_pop(luaVM, 1); // items
> // After your pcall, non-error case:
> lua_getglobal(luaVM, "MyTable); // table
> lua_getfield(luaVM, -1, "n"); // table, n
> for (int i = 0, n = luaL_tointeger(luaVM, -1); i < n; ++i)
> lua_rawgeti(luaVM, -2, i + 1); // table, n, item[i]
> // DO STUFF with item on top of stack
> lua_pop(luaVM, 1); // table, n
> lua_pop(luaVM, 2);