简体   繁体   中英

Lua references between objects

I implemented Simple Lua class in C. Usage of class:

require("test")
function foo()
    local t1 = test()
    local t2 = test()
    t1:attach(t2)
    return t1
end
o = foo()
-- some code
o = nil

attach function:

int class_attach(lua_State *L)
{
    module_data_t *mod = luaL_checkudata(L, 1, "test");
    luaL_checktype(L, 2, LUA_TUSERDATA);
    module_data_t *child = lua_touserdata(L, 2);
    printf("%p->%p\n", (void *)mod, (void *)child);
    return 0;
}

After return from function t2 object is cleaned by gc. Is it possible to prevent that. Set reference between t1 and t2 objects? (calling __gc metamethod (of t2 object) only after parent module (t1) is cleaned).

Simple way is use table:

function foo()
    ret = {}
    ret[1] = test()
    ret[2] = test()
    ret[1]:attach(ret[2])
    return ret
end

but that is not fun way. Thanks!

I've had the same issue in the past. The simple reason for this is that Lua doesn't know about the connection established in C code (there's none right now, but I guess it's going to be done somewhere).

You don't have to do the table approach, just link the two objects/tables/whatever on the Lua side as well:

function foo() 
    local t1 = test() 
    local t2 = test() 
    t1:attach(t2)
    t1._dummy_link = t2
    return t1 
end 

Just keep in mind that's only good for 1:1 relationships. For more complex stuff you'll still have to use some kind of table or a similar approach. The probably cleanest way to do this would be doing the linking on the Lua side and just adding a callback to C in case there's C code to be run as well.

You can set it in the Lua registry. This is effectively a global table which can only be accessed in C code. You can set registry[t1] = t2; . As long as you unset this appropriately in t1 's __gc . This can also scale to 1:n mappings, as you could do, for example, registry[t1].insert(t2) for multiple "children".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM