[PyKDE] SIP and typedefs in signals

Gerard Vermeulen gerard.vermeulen at grenoble.cnrs.fr
Sun Jan 7 16:23:00 GMT 2007


On Wed, 20 Dec 2006 16:41:22 +0000
Phil Thompson <phil at riverbankcomputing.co.uk> wrote:

> On Monday 18 December 2006 7:34 pm, Gerard Vermeulen wrote:
> > Hi,
> >
> > moc does not expand typedefs in signals but sip does.
> > Therefore I needed a hack to wrap the following header code:
> >
> > --- start C++ header code ---
> > typedef QPointF QwtDoublePoint;
> >
> > class QWT_EXPORT QwtPlotPicker: public QwtPicker
> > {
> >     Q_OBJECT
> >     ...
> > signals:
> >     // Here, moc produces code containing QwtDoublePoint and not QPointF.
> >     void selected(const QwtDoublePoint &pos);
> > };
> > --- end C++ header code ---
> >
> > --- start SIP declaration ---
> > // The C++ library declares
> > // typedef QPointF QwtDoublePoint;
> > // but that does not work in SIP (Python crashes, when using the typedef).
> 
> When does it crash? When you call connect()? When the signal is delivered?
> 
> > // However the following SIP declaration
> > class QwtDoublePoint: QPointF
> > {
> > %TypeHeaderCode
> > #include <qpoint.h>
> > %End // %TypeHeaderCode
> > };
> > // does work.
> >
> > class QwtPlotPicker: QwtPicker
> > {
> > %TypeHeaderCode
> > #include <qwt_plot_picker.h>
> > %End // %TypeHeaderCode
> >     ...
> > signals:
> >     void selected(const QwtDoublePoint&);
> >     // void selected(const QRectF&); without typedef may have worked
> > before, // but not with SIP-4.5.x.
> > };
> > --- end SIP declaration ---
> >
> > Is it possible (or worthwhile) to make SIP behave like moc for such cases?
> 
> I don't think that this is the problem. SIP supports the use of typedefs in 
> signal arguments - see sipFindSigArgType() in siplib.c. As they are not used 
> very much I think the problem is more likely to be a bug in that function.
> 
Yes, it is a bug:

(gdb) run bug.py      
Starting program: /home/packer/usr/bin/python bug.py
[Thread debugging using libthread_db enabled]
[New Thread 47234504940432 (LWP 16756)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 47234504940432 (LWP 16756)]
0x00002af5a4f4a53c in findClassArg (emd=0x0, name=0x2aaaab7f87f1 "QPointF", 
    len=7, at=0xc5b870, indir=0) at siplib.c:6964
6964        sipWrapperType **wtp = emd->em_types;
(gdb) bt
#0  0x00002af5a4f4a53c in findClassArg (emd=0x0, 
    name=0x2aaaab7f87f1 "QPointF", len=7, at=0xc5b870, indir=0)
    at siplib.c:6964
#1  0x00002af5a4f4a8e9 in sipFindSigArgType (name=0xba92d0 "QwtDoublePoint", 
    len=14, at=0xc5b870, indir=0) at siplib.c:7106
#2  0x00002af5a4f4bb47 in parseSignature (
    sig=0x2aaaafa8bbdc "2selected(QwtDoublePoint)") at qtlib.c:343
#3  0x00002af5a4f4be1d in createUniversalSlot (txSelf=0x2aaaaf73bea8, 
    sig=0x2aaaafa8bbdc "2selected(QwtDoublePoint)", rxObj=0x2aaaafa9bde8, 
    slot=0x0, member=0x7fff0742d830) at qtlib.c:448
#4  0x00002af5a4f4cf28 in sip_api_convert_rx (txSelf=0x2aaaaf73bea8, 
    sig=0x2aaaafa8bbdc "2selected(QwtDoublePoint)", rxObj=0x2aaaafa9bde8, 
    slot=0x0, memberp=0x7fff0742d830) at qtlib.c:915
#5  0x00002af5a4f4d06d in sip_api_connect_rx (txObj=0x2aaaaf73bea8, 
    sig=0x2aaaafa8bbdc "2selected(QwtDoublePoint)", rxObj=0x2aaaafa9bde8, 
    slot=0x0, type=0) at qtlib.c:961
#6  0x00002af5a3f5f25d in initQtCore ()
   from /home/packer/usr/lib/python2.5/site-packages/PyQt4/QtCore.so
#7  0x000000000047f3c4 in PyEval_EvalFrameEx ()
#8  0x0000000000480314 in PyEval_EvalFrameEx ()
#9  0x0000000000480314 in PyEval_EvalFrameEx ()
#10 0x0000000000480e2b in PyEval_EvalCodeEx ()
#11 0x00000000004810d2 in PyEval_EvalCode ()
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) bt full
#0  0x00002af5a4f4a53c in findClassArg (emd=0x0, 
    name=0x2aaaab7f87f1 "QPointF", len=7, at=0xc5b870, indir=0)
    at siplib.c:6964
        i = 0
        wtp = (sipWrapperType **) 0xba92d0
#1  0x00002af5a4f4a8e9 in sipFindSigArgType (name=0xba92d0 "QwtDoublePoint", 
    len=14, at=0xc5b870, indir=0) at siplib.c:7106
        tem = (sipExportedModuleDef *) 0x0
        tn = 0x2aaaab7f87f1 "QPointF"
        tnlen = 7
        tdd = (sipTypedefDef *) 0x2aaaab958140
        em = (sipExportedModuleDef *) 0x2aaaab954340
        po = (sipPyObject *) 0x7fff0742d440
#2  0x00002af5a4f4bb47 in parseSignature (
    sig=0x2aaaafa8bbdc "2selected(QwtDoublePoint)") at qtlib.c:343
        btlen = 14
        unsup = 0
        isref = 0
        indir = 0
        sat = unknown_sat
        arg = 0xba92d0 "QwtDoublePoint"
        a = 0
        dp = 0xba92d0 "QwtDoublePoint"
---Type <return> to continue, or q <return> to quit---


and the problem is in the else-block of the lines

                    /*
                     * Find the module that this class,
                     * mapped type or enum is defined in.
                     */
                    if (tdd->tdd_mod_name == NULL)
                        tem = em;
                    else
                        for (tem = clientList; tem != NULL; tem = tem->em_next)
                            if (strcmp(tem->em_name, tdd->tdd_mod_name) == 0)
                                break;
in sipFindSigArgType()

Stepping leads to:

(gdb) s
7098                                if (strcmp(tem->em_name, tdd->tdd_mod_name) == 0)
(gdb) p tem->em_name
$12 = 0x2b8f56b9301d "PyQt4.QtCore"
(gdb) p tdd->tdd_mod_name
$13 = 0x2aaaab7f840f "QtCore"
(gdb) 

which does not match and tem ends up being NULL


Gerard




More information about the PyQt mailing list