[PyKDE] SIP questions

Jim Bublitz jbublitz at nwinternet.com
Wed Apr 2 09:13:01 BST 2003


On 02-Apr-03 Claus, Richard wrote:
> I have used SIP to provide Python access to a set of C++ classes
> I wrote.  These classes don't involve either PyQt or Qt.
> 
> A few points:
> 1) I have a placement operator new(size_t sz, void* p, bool swap)
> in one of the classes.  It is used internally to the C++ code and
> is not exposed to Python.  When the SIP-generated code is
> compiled by VS.NET, it complains about the lack of existance of th
> e standard new operator in the code generated for the class
> constructors, although it has no problem finding it for classes
> not having additional operator news defined.  I would have
> thought that it should be able to figure out which new to use
> from the sig nature.  I saw two solutions: 1) Provide a new
> operator in my class that has the behaviour of the standard one,
> or 2) use the scoping operator (i.e. ::new MyClass) in
> %MemberCode.  I had to handle the delete operator similarly. 
> What's the right thing to do?  Should SIP be using the scoping
> operator in the generated code?

I'm not at all sure on this one, but it sounds to me like either of
your solutions would be worth trying. I'm not familiar with VC, but
I seem to recall that some versions of C++ used to have a "standard"
new operator that globally overloaded the "real" new operator - if
new is defined in an h file, you could try including that h file.
 
> 2) Some of my C++ classes have pure virtual functions.  The SIP
> generated code looks like:
> int sipMyDatagramIterator::process(MyDatagram * a0)
> {
>       if
> (sipIsPyMethod(&sipPyMethods[0],sipPyThis,sipName_PKG_MyDatagramIt
> erator,sipName_PKG_process))
>               return
> sipMyDatagramIterator::sipVH_process(&sipPyMethods[0],sipPyThis,a0
> );
> }
> 
> about which VS.NET rightfully complains:
> c:\pkg\sippkgmydatagramiterator.cpp(61) : warning C4715:
> 'sipMyDatagramIterator::process' : not all control paths return a
> value

What sip requires for pure virtuals/abstract classes is that:

a. methods be declared in the sip file as pure virtual

   virtual void foo (int) = 0;

b. *all* pure virtuals for the class be declared in the sip file
(even if they're private). 

I haven't seen a problem, but PyKDE only has a handful of abstract
classes.

> I tried copying this and adding an else clause in %MemberCode,
> but it didn't work.  I don't remember why.

It probably didn't work because to add %MemberCode to a virtual
method you also need to add a %VirtualCode block - there should be
some examples in PyQt; if not, check the C++ code that sip
generates for a virtual method that works, for example for a
virtual method 'foo' there will be a sipSomeClass::foo method and a
sipSomeClass::sipVH_foo method - the latter is the %VirtualCode
block that sip generated (the VH method will only appear in the base
class that defines the virtual method, I believe).
 
> 3) I'm concerned about speed.  I'd like certain class methods to
> provide access to Numeric or NumArray style arrays, but haven't
> figured out how to do that yet.  In the mean time, I am trying to
> avoid a copy by returning PyBuffer_* in %MemberCode instead of
> PyString_*.  However, this leads to wanting to pass PyBuffers
> into the C++ code and I haven't managed to figure out how to tell
> sipParseArgs to accept them.  Any suggestions?

Here's a fragment from a method that takes a Python list in place
of the C++ char** argument. The 'T' format specifier in
sipParseArgs (along with the PyList_Type and slist arguments)
handles the Python object. The first int argument isn't passed in
from Python, but is computed in the C++ code - a1 is the second
int arg. The '|' means the int arg is optional, 'm' is for the
the 'this' or 'self' pointer.

void insertStrList (const char**, int = -1, int = -1);
%MemberCode
//returns  
//takes list (a Python list of strings) index (int)

    KEditListBox *ptr;
    PyObject *slist;
    int a1 = -1;
    int n;

    if (sipParseArgs(&sipArgsParsed, sipArgs, "mT|i",
        sipThisObj,sipClass_KEditListBox, &ptr,
        &PyList_Type, &slist, &a1))
    {
        if ((n = PyList_Size (slist)) == 0)
            return NULL;

 
> Finally, I've fallen into trouble with Python's garbage
> collection in that  when I use my code in a multithreaded
> environment, Python sometimes exits with a complaint about
> finding an object on its GC list that has already been collected
> (currently not so easy to reproduce, so I don't have an exact
> copy of the error message).  Given that SIP handles reference
> counting, can anyone give me some suggestions for going after
> this?  The placement new on an existing Python string trick is
> little more than casting to give the string a personality. 
> Maybe this is confusing SIP somehow?

I have no idea on this one.

Jim




More information about the PyQt mailing list