[PyQt] SIP and virtual functions

Jens Thoms Toerring jt at toerring.de
Tue Nov 23 14:22:39 GMT 2010


Hi,

I've got some problem with sip when using classes that have
virtual methods. The classes look somewhat like this (this is,
of course, just an example, cut down to the absolute essen-
tials and not my real code):

-------- Foo.hpp ------------------------------
#if ! defined FOO_HPP_
#define FOO_HPP_

class A {
    friend class B;
  private:
    A( double & x );
};

class B {
  public:
    virtual A a( );
  private:
    double m_x;
};

class C : public B {
};

#endif
-------- Foo.cpp ------------------------------
#include "Foo.hpp"

A::A( double & x ) { x = 3; }

A B::a( ) { return A( m_x ); }
----------------------------------------------

Now I have a Foo.sip file

-------- Foo.sip ------------------------------
%Module PyFoo 0

class A  /NoDefaultCtors/
{
%TypeHeaderCode
#include "Foo.hpp"
%End
};

class B
{
%TypeHeaderCode
#include "Foo.hpp"
%End
  public:
    virtual A a( );
};

class C : B
{
%TypeHeaderCode
#include "Foo.hpp"
%End
};
---------------------------------------------

This sip file results in the creation of the following function
in the sipPyFoocmodule.cpp file

A sipVH_PyFoo_0(sip_gilstate_t sipGILState,PyObject *sipMethod)
{
    A sipRes;
    PyObject *resObj = sipCallMethod(0,sipMethod,"");

    if (!resObj || sipParseResult(0,sipMethod,resObj,"H5",sipType_A,&sipRes) < 0)
        PyErr_Print();

    Py_XDECREF(resObj);
    Py_DECREF(sipMethod);

    SIP_RELEASE_GIL(sipGILState)

    return sipRes;
}

and there's a problem with the first line of this function: the
constructor of class A is private - and that's by design since
A is only to be instantiated via class B. The function a() in B
for creating an instance of A must be virtual since class C (or
some other derived class) must be able to have it's own version
of the a() function to do some extra checks before explicitely
invoking the base class B::a() function - and the 'virtual'
qualifications seems to be at the heart of the problem, with-
out it the above function doesn't get generated.

I have played around with all kinds of annotations but found no
way to avoid the creation of this kind of function (or it's attempt
to invoke a private constructor). In my real code in somewhat more
complex situations also non-existing constructors are attemted to
be used (e.g. constructors with a single int argument which don't
exist at all).

Has anyone an idea what I'm doing wrong and/or how to resolve
this issue?
                       Thanks and best regards, Jens
-- 
  \   Jens Thoms Toerring  ________      jt at toerring.de
   \_______________________________      http://toerring.de


More information about the PyQt mailing list