Let's start with

"qtgui/QPushButton.cpp"

HB_FUNC( QT_QPUSHBUTTON_SETAUTODEFAULT )
{
   hbqt_par_QPushButton( 1 )->setAutoDefault( hb_parl( 2 ) );
}

Since
#define hbqt_par_QPushButton( n )                   ( ( QPushButton
             * ) hbqt_gcpointer( n ) )

this line:
hbqt_par_QPushButton( 1 )->setAutoDefault( hb_parl( 2 ) );
becomes:
( ( QPushButton * ) hbqt_gcpointer( 1 ) )->setAutoDefault( hb_parl( 2 ) );

In "hbqt_destruct.cpp" there is hbqt_gcpointer(). Its job is to return
the pointer to the object.

For every Qt object hbqt actually stores a struct, and in pq member it
stores a "guarded pointer" that is binded to the object at creation
time. A guarded pointer is a special pointer that is guaranteed to
became NULL if the binded object is deleted. QPointer may only be
created for objects descending from QObject.

Guarded pointers are important since (from what I understood from my
readings) there are many different possibilities for object
destruction, for example using MT, where a thread can delete an object
while another is updating it...

In the objects destructor ( the hbqt_gcRelease_* functions ) pq value
is checked against NULL... But in hbqt_gcpointer it is not... because
in hbqt_gcpointer we just have a "generic" QGC_POINTER and not the
"specific" QGC_POINTER_QPushButton so pq is not "available"...
See:
typedef struct
{
   void * ph;
   bool bNew;
   QT_G_FUNC_PTR func;
   QPointer< QPushButton > pq;
} QGC_POINTER_QPushButton;

typedef struct
{
  void * ph;
  bool bNew;
  QT_G_FUNC_PTR func;
} QGC_POINTER;

My idea is then to add a Qpointer placeholder in QGC_POINTER but it
would need some more changes, infact it seems ok for objects in
directory qtgui (they descend from QObject) but not for objects in
qtcore that doesn't inherit from QObject.

So there are 2 possibilities to verify:

1) in hbqt.h change the #define hbqt_par_QPushButton( n )   ( (
QPushButton  * ) hbqt_gcpointerFromQObject( n ) ) for object in qtgui
and then copy hbqt_gcpointer to hbqt_gcpointerFromQObject adding pq
checking (the some for *FromObj) but then how to handle Q_release ?

2) using bNew not as a bool but as a bitmask with values
1=CREATED_BY_NEW 2=HAS_PQ 4=INVALID 8=DELETE_IN_PROGRESS (to
trap/debug strange interactions between c++ delete and harbour GC)
giving us a clear picture of what is happening and also a lot more
"status" bit to use

Using 2) it may be just a matter of adding the status bit at object
creation and checking the 1-ness of bit 2 before testing pq and some
other trivial changes...


Francesco
_______________________________________________
Harbour mailing list (attachment size limit: 40KB)
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour

Reply via email to