[PyKDE] SIP and typedefs in signals
Phil Thompson
phil at riverbankcomputing.co.uk
Sun Jan 7 17:43:18 GMT 2007
On Sunday 07 January 2007 4:08 pm, Gerard Vermeulen wrote:
> 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
Try tonight's snapshot. It's a code generation bug, but PyQt doesn't use the
bad code.
Phil
More information about the PyQt
mailing list