It seems to me that you're probably going about implementing your script interface the wrong way.
If you're reloading scripts, that generally means some level of teardown and rebuilding of the mirror C++ objects that talk to them. For example, if you have a Lua script that runs the AI for an entity, there would be some C++ object that represents that AI. That object is responsible for communicating with the Lua script (so that external code is insulated from knowing that a Lua script is even involved).
That object needs to be destroyed and rebuilt with the newly loaded script.
let Lua do whatever it will without having to destroy / rebuild / manage anything on the C++ side.
If you want Lua to be in charge of this, then this means that Lua be in charge of this. With great power comes great responsibility. And if you want Lua to have the power, then the onus is now on Lua to have the responsibility to use it correctly.
If Lua hands some "function" to C++, then it is the responsibility of the Lua script to ensure that this function is properly and transparently updated when scripts change. There are several ways to do this in Lua. One way is to build a simple stub function which searches some global registrar object for the actual function to call:
local stubForDoStuff = function(...)
You can even make a simple stub generator function (it would need to be more complex to find things that aren't direct members of the registrar):
When a script changes, you simply update the functions in the
Registrar. There are more complex ways of doing it, by giving C++ code tables that contain metamethods for
__call that will go track down the actual function or whatever. But this is the simplest and most obvious method of doing it.
This sort of complexity is generally why I don't give Lua this power. I want to focus my Lua scripts on doing their actual job, rather than updating functions and other nonsense. So I give C++ the responsibility for managing Lua-created object loading and destroying.
I tend to use Lua scripts as an alternate means of instantiating C++ derived classes. So "reloading a script" means destroying an object and replacing it with a new one.