Re: [luabind] Dangling pointers Lua style...
Brought to you by:
arvidn,
daniel_wallin
From: eduard m. <mue...@go...> - 2010-09-30 23:58:54
|
We had the same problem: access to dead objects from within Lua should always cleanly fire Lua errors instead of crashing. We ended up in using our own weak_ptr impl to solve this. If there are more elegant solutions to solve this problem (invalidating all refs in Lua as soon as the C++ object dies for example), I would also be very interested to hear about this. Our weak ptr basically works like: === /* baseclass for something a WeakPtr can point to */ class WeakReferenceable { public: virtual ~WeakReferenceable() { // Invalidate all weakptrs that point to "this" (accesses a static map // of all registered WeakReferenceables) WeakPtrBase::WeakRefDying(this); } }; /* non templated baseclass for a WeakPtr */ class WeakPtrBase { public: WeakPtrBase(WeakReferenceable* ptr) : _weak_ptr(ptr) { // keep track of WeakPtrBase <-> Weakreferenceable links in a static map RegisterWeakRef(this, ptr); } ~WeakPtrBase() { // get rid of WeakPtrBase <-> Weakreferenceable links in the static map UnregisterWeakRef(this, _weak_ptr); } protected: virtual void WeakReferenceableDying() = 0; }; === /* final weak ptr impl. Guaranteed to point to NULL or a valid object. Can only wrap WeakReferenceable's */ template <class Class> class WeakPtr { public: WeakPtr(Class* ptr) : WeakPtrBase(ptr), _class_ptr(ptr) { } private: virtual void WeakReferenceableDying() { // invalidate our pointer to the deleted object _class_ptr = NULL; } // ptr access, copy and stuff... }; ==== Then in luabind: // hold objects in WeakPtrs always: class MyClass : public Weakreferenceable { } class_<MyClass , WeakPtr<MyClass> >("myclass") // pointer access from luabind can now deal with NULL pointers template<class T> T* get_pointer(WeakPtr<T> const& Ptr) { if (Ptr.Object() == NULL) { throw std::logic_error("trying to access an object which is not or no longer available."); } return Ptr.Object(); } === get_pointer above assumes that accessing a NULL WeakPtr is an error. If you want to allow NULL access, then this of course can't make the Lua objects nil. You would have to add an extra function, like i.g: is_ptr_valid(WeakPtr<T>) to check for NULL in Lua... Hope it helps. Let me know if you are interested in the complete impl... Greets, Eduard On Fri, Oct 1, 2010 at 00:52, Nigel Atkinson <ni...@at...> wrote: > Yes, that would work. Thank you. > > I was trying to think of a generic solution, such as some sort of > "ward_ptr" that threw an exception on getPointer() if it was invalid. > However the problem is - how would such a class "know" when the pointer > it contains has been free'd. It probably could be done via, heap > debugging functions or some such, but that's just yuck. (Slow, > non-portable, etc) > > A wrapper class it is methinks! But hang on moment... > would this work?? How clever is Luabind about this... > > void Destroy( ward_ptr<myclass> ptr ) > { > ptr->Destroy(); > ptr.invalidate(); > } > > class_<myclass, ward_ptr>("myclass") > [ > .def("Create", MakeOne ) // MakeOne would return a myclass* > bla bla bla > .def("Destroy", Destroy ) > ] > > Hmmmmm. > > Nigel > > On Thu, 2010-09-30 at 13:17 -0400, Evan Wies wrote: >> You can try wrapping the Create/Destroy in a proxy class that uses >> constructors/destructors instead? It depends on how pervasive this >> idiom is in your code. From there, Luabind is pretty flexible with how >> you can bind arbitrary functions to classes. >> >> If you want to explicitly control lifetimes, check out how Corona deals >> with a similar problem: >> http://developer.anscamobile.com/content/application-programming-guide-graphics-and-drawing#Removing_Objects_Properly >> >> -Evan >> >> >> On 09/30/2010 09:28 AM, Nigel Atkinson wrote: >> > Consider a bound class without a bound constructor. Instead elsewhere >> > there is a bound function to create and another to destroy. >> > >> > Used something like this... >> > >> > obj = CreateObject() >> > >> > -- use the obj >> > >> > DestroyObject( obj ) >> > >> > The destroy might do more, but ultimately deletes the object. Problem >> > is in Lua, we now have a dangling pointer! obj after the destroy call >> > still points somewhere, and if you accidentally use it bad things >> > happen. Not good if the Lua scripts are from the end user. They can't >> > be expected to write "obj = nil" after each call. :) >> > >> > So how to automatically set obj to nil after a destroy call? >> > >> > My thoughts lean towards “All problems in computer science can be solved >> > by another level of indirection” >> > >> > In this case some sort of smart/auto pointer, and wrapper functions that >> > throw exceptions if the passed pointer points to bad data? >> > >> > What are everyone's thoughts? I have the feeling I've missed some >> > obvious answer. >> > >> > >> > ------------------------------------------------------------------------------ >> > Start uncovering the many advantages of virtual appliances >> > and start using them to simplify application deployment and >> > accelerate your shift to cloud computing. >> > http://p.sf.net/sfu/novell-sfdev2dev >> > _______________________________________________ >> > luabind-user mailing list >> > lua...@li... >> > https://lists.sourceforge.net/lists/listinfo/luabind-user >> >> >> >> ------------------------------------------------------------------------------ >> Start uncovering the many advantages of virtual appliances >> and start using them to simplify application deployment and >> accelerate your shift to cloud computing. >> http://p.sf.net/sfu/novell-sfdev2dev >> _______________________________________________ >> luabind-user mailing list >> lua...@li... >> https://lists.sourceforge.net/lists/listinfo/luabind-user > > > > ------------------------------------------------------------------------------ > Start uncovering the many advantages of virtual appliances > and start using them to simplify application deployment and > accelerate your shift to cloud computing. > http://p.sf.net/sfu/novell-sfdev2dev > _______________________________________________ > luabind-user mailing list > lua...@li... > https://lists.sourceforge.net/lists/listinfo/luabind-user > |