lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I got a little lost somewhere along this thread so this may already
have been suggested by another poster but regarding the original
poster's question and unless I understand something incorrectly the
only thing that needs to be done is to pass a reference to the lua
callback function.  So assuming we have a function register_callback
(callback_function cb, void *ud) you'd only need to define a callback
function like so:

struct context {
    int reference;
    lua_State *state;
};

static void callback (void *ud)
{
    struct context c;

    c = (struct context *)ud;

    lua_rawgeti (c->state, LUA_REGISTRYINDEX, c->refernece);
    /* Possibly push additional args here. */
    lua_call (c->state, 0, 0);
}

void register_lua_callback(lua_State *L, int index)
{
    struct context *c = malloc (sizeof (struct context));

    c->state = L;

    /* index here is assumed to be the stack position of the lua
callback function. */

    lua_pushvalue (L, index);
    c->reference = luaL_ref (L, LUA_REGISTRYINDEX);

    register_callback ((callback_function) callabck, (void *)c);
}

The code above is for display purposes only anf probably does not
compile.  Apart from that, there's also the option of keeping the Lua
state as a global variable which simplifies things a  lot.  You can
then simply pass the reference cast to (void *) directly to the
callback and avoid the need to allocate and use the context struct.
Book-keeping and deallocation of the context as well as unreferencing
of the callback function depends on the general application
organization but should be straightforward.

On Tue, Mar 13, 2012 at 11:52 AM, Peter Pimley <peter.pimley@gmail.com> wrote:
> I quite like the new-thread approach.  That means you only ever have a
> lua_State* on the C side of things, so no there's need to define and do
> housekeeping for any new structs.
>
> It would be something like:
> (Let's hope my formatting gets preserved!)
>
> Push your lua callback function onto your lua state.
> Call your newly written register_lua_func, passing in the state.  It would:
> Pop the function
> Push a new thread
> Put the new thread somewhere in the main state's registry so that it doesn't
> get garbage collected.
> Push the function onto the new thread.
> Pass the new lua_State as the userdata to the C register function.
>
> With respect to steps 3 and 6; Is there an easy way to move the function
> from one lua_State's stack to another's?  It's been a few months since I did
> any Lua.  Maybe you could you do it via the registry?
>
> You C callback would be trivial:
>
> Cast the void * to a lua_State
> lua_pushvalue(L, -1) // push a duplicate of the lua callback function
> Push any args
> lua_call(L, ...)
> Pop any results
> (original function remains on the stack)
>
> Peter
>