[PyQt] SIP and virtual functions
Phil Thompson
phil at riverbankcomputing.com
Tue Nov 23 14:42:59 GMT 2010
On Tue, 23 Nov 2010 15:22:39 +0100, Jens Thoms Toerring <jt at toerring.de>
wrote:
> 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?
Not every C++ class can be wrapped. SIP often has to create temporary
instances which obviously requires support from the underlying C++.
Phil
More information about the PyQt
mailing list