c++clualuajit

Pass opaque LUA data through C++


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.


Solution

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