Home > Net >  Pass opaque LUA data through C
Pass opaque LUA data through C

Time:10-20

I have the following scenario: A LUA function LuaFuncA calls a C function CPPFunc and passes an argument Arg, which is opaque to the CPP function and could be anything (whether nil, number, userdata etc.) and cannot be assumed to be of the same type each time CPPFunc is called.

LuaFuncA then terminates and only C code is running. After a certain amount of time (which could be anything, from milliseconds to hours) CPPFunc needs to call another LUA function LuaFuncB and pass Arg.

Attempting the native solution of using lua_getpointer(L, 1) then pushing it back with lua_pushlightuserdata(L, 1) (L seems to be the same handle in both calls) results in the following error:

attempt to index local 'Arg' (a userdata value).

(in this case Arg was {1, 2, 3, 4} and I attempted to print Arg[2])

Thank you for any advice!

EDIT: CPPFunc is a task scheduler routine. LuaFuncA basically registers LuaFuncB as a task, from which point CPPFunc need to call LuaFuncB at regular intervals, which means that the state must be either preserved or recreated before each call.

EDIT 2: The program is cross-platform and must be able to run natively on both Linux and Windows, therefore platform specific calls such as fork() cannot be used.

CodePudding user response:

Since you're calling Lua functions from C/C , you must have at least one lua_State, where the value in question is.

If during "LuaFuncA then terminates and only C code is running" you still keep that state around until you need the value again, then you don't need to change anything. Simply remember the index at which the value is, then access it again when needed, e.g. with lua_pushvalue to get it toward the top for a lua_call.

If you do "use up" the value at some point (i.e. you call a function that pops it), then you can create a copy with lua_pushvalue and move it down the stack with lua_insert to an index where it can stay until later.

And if you can't keep the original state around, then you can simply create a separate one with lua_newstate, move your value (or a copy) to that state with lua_xmove, and later move it back to any other state when you need it.

CodePudding user response:

You can use the Lua registry and reference mechanism for this. With Arg on top of the stack, do int ref = luaL_ref(L, LUA_REGISTRYINDEX);. That will pop it and save it to the registry, with ref being your key to retrieve it later. You can then save ref as you would any other int in C or C . To retrieve Arg and push it back onto the stack, do lua_rawgeti(L, LUA_REGISTRYINDEX, ref);. If you won't need to retrieve it again, do luaL_unref(L, LUA_REGISTRYINDEX, ref); to clean up after yourself.

  • Related