So with the Lua C API you can save a Lua value in the registry and retrieve it later. There are different ways to do it, you can create a variable and use it's pointer as the key in the registry as it's always unique. You would push the pointer as light userdata.
You can also create a reference using
Lua registry is just another lua table, easily accessible via predefined "special" index. I guess you don't need explanations on how Lua table is different from light userdata.
It doesn't really matter how you will index registry table, as long as you can store that key on C/C++ side. For your convenience there's already functions (luaL_ref/luaL_unref) giving you integer key that is easy to store and move around.
About garbage collection - rules are always the same. As long as value is stored in table that wasn't marked as weak table (registry is not weak table), that value won't be cleared. You must explicitly remove value from the registry.
Changing value will obey normal Lua rules. Assigning new immutable value to some variable won't change value stored in registry, i.e. registry won't follow updates to some variable. But changing content of mutable value (table etc) is ok, since registry and variable will refer same value.