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.