Snapchat / djinni

A tool for generating cross-language type declarations and interface bindings. Djinni's new home is in the Snapchat org.
Apache License 2.0
173 stars 50 forks source link

Lifetime guarantees of C++ instances being hold as weak_pointer in C++ layer and tracked in ios/android level #147

Closed martin00001313 closed 1 year ago

martin00001313 commented 1 year ago

Based on current implementation of Djinni, there is no lifetime specification of instances being declared in C++ with weak pointer(aka std::weak_ptr) and returned to platform(e.g. ios side), as the djinni auto-generator returns just 'T*' to ios level w/o any additional lifetime specifications. The only platform side holder is 'proxy-cache' which however has no specification of lifetime of the instance.

Below is an example of such case: --- In djinni we have: ` IT1 = interface +c {}

Manager = interface +c { get_instance(): IT1 } --- In C++ we have std::weak_ptr instance; std::shared_ptr Manager::GetInstance() { std::shared_ptr res{instance.lock()}; if (nullptr == res) { res = std::make_shared(); instance = res; }

return res; // return to ios/android level w/o any save in C++ side (i.e. just weak pointer) } ---- ios level let ist1 = Manager::getInstance(); // this will return raw pointer to the interface -> no lifetime specification ///. save the pointer and work in ios level only. can pointer became dangling/invalid as there is no life-time guarantees/holders in C++ layer? ` -------- END

Are there any plans to provide additional constraints on top of lifetime for such object instances.

martin00001313 commented 1 year ago

Under the discussion of https://github.com/cross-language-cpp/djinni-generator/discussions/149

li-feng-sc commented 1 year ago

The lifetime management in Djinni is well defined and correct (as far as I can tell). Object pointers in ObjC are NOT raw pointers, they are smart pointers similar to shared_ptr<> and managed by compiler ARC.

martin00001313 commented 1 year ago

Thanks for the update! Right, NSObject is handling the lifecycle.

Now just trying to get the right path for vice versa communication, i.e. having an object being created in ios/android layer and keeping a weak ref.(aka std::weak_ptr) in c++ layer. How lifetime specification can be provided there and if it's possible to just track a weak ref in c++ layer.

Based on current design and language limitations, I see the only way is to hold a strong ref. (i.e. shared_ptr) in C++ layer for the objects being created/instantiated on objectiveC/java layer

li-feng-sc commented 1 year ago

It works like this:

NSObject* --holds--> shared_ptr<> in proxycache --holds--> C++ object. <--weakly_holds-- weak_ptr<> in your code

Whether you have a weak_ptr<> in your C++ code does not affect the life time of the C++ implementation object. It will work as you expected as if the NSObject* pointer is another shared_ptr<> in C++.

li-feng-sc commented 1 year ago

If ObjC pointer owns the last reference to the C++ object, then dropping the ObjC pointer will destroy the C++ object, this is exactly the same like a shared_ptr<>. After that, you weak_ptr<> in C++ becomes expired.