[Kde-bindings] Problem condition in Qyoto MethodCall
richard.j.dale at gmail.com
Sat Feb 10 17:01:43 UTC 2007
On Saturday 10 February 2007, Arno Rehn wrote:
> Am Samstag, 10. Februar 2007 schrieb Arno Rehn:
> > Am Samstag, 10. Februar 2007 schrieb Richard Dale:
> > > This is wrong, but I still haven't worked out what the correct version
> > > should be:
> > >
> > > // We have to check here, if our target does still exists.
> > > // If there is no entry in the weakRef Dictionary, the instance doesn't
> > > exist anymore.
> > > // There's also no entry, if the method is a constructor or the method
> > > is static.
> > > // If the target doesn't exist anymore, set _called to true so the
> > > method won't be invoked.
> > > // The other possibility is that the qApp was just destroyed and we
> > > want to call a destructor.
> > > // This could lead to a crash when we interfere with the destroying
> > > mechanism of Q(Core)Application.
> > > if ( ((getPointerObject(_current_object) == 0) && !_ctor &&
> > > !(_tmp.flags & Smoke::mf_static))
> > >
> > > || ((_tmp.flags & Smoke::mf_dtor) && (qApp == 0)) )
> > >
> > > _called = true;
> > >
> > > Not every instance has an entry in the weak reference map. For example,
> > > I had a QVariant which was created in C++ code and it failed the
> > > condition and '_called' was set to true. Try the qdbus/pingpong example
> > > - it crashes when trying to access to QVariant returned.
> > Oops, didn't know that not every instance is in the weakRef map.
> > > We should only be looking at the 'o' and 'o->ptr' values and not call
> > > the method if they are zero and it's not a static method or
> > > constructor. I don't think we need to test for destructors at all
> > > because 'o->ptr' is set to 0 once something has been deleted (or it
> > > should be anyway).
> > Uhm, actually if we just test for o->ptr == 0 and the method not being a
> > constructor it doesn't work. My code:
> > if ((_current_object == 0) && !_ctor)
> > _called = true;
> > Result:
> > *** glibc detected *** mono: free(): invalid pointer: 0xb6b94c9c ***
> > at startup.
> > As the problem with destructors just happens when the qApp is about to
> > quit I think we shouldn't test for something being null at all, just if
> > it is a destructor and if the qApp is about to quit. If so, don't call
> > the destructor. If it still crashes somewhen else because the underlying
> > C++ instance doesn't exist anymore, the problem will probably have
> > another cause.
> Ok, that won't work, I didn't think about that it is possible to not have
> called QCoreApplication::exec and still can do something with Qt. But just
> checking for o->ptr being 0 won't work either, as I've already stated.
Ah, ok. This is the thing I love about systems programming - you can
spend about two weeks thinking about the correct version of a single
line of code. I think o->ptr is only set to zero for something which
was created in the C# side, but for an instance created in the C++
side I think we need to not call the delete method when the destructor
is called, and we do need to set o->ptr to zero.
More information about the Kde-bindings