[PyQt] A question regarding SIP

Phil Thompson phil at riverbankcomputing.com
Mon Feb 22 11:04:21 GMT 2010


On Mon, 22 Feb 2010 07:48:01 +0530, Ravi kumar <ravi.kumar.039 at gmail.com>
wrote:
> Hello
> 
> I am learning SIP, and have a small question regarding it. Let me
> explain the situation :
> 
> I have a small test library written in C++. It is made up of two
> files, test.hpp and test.cpp
> with declarations and implementation respectively. There is a
> particular declaration that
> goes like this :
> 
> namespace Test {
> 	...
> 
> 	class KlassProcessor {
> 		...
> 
> 		virtual void process2 (...) {
> 			...
> 		}
> 	};
> }
> 
> I successfuly written a python extension using SIP, and the extension
> is named : test
> So, to use KlassProcessor, one may do like this in python :
> 
> from test import Test
> kp = Test.KlassProcessor ()
> kp.process2 (...)           # ... are arguments, not part of my problem
> 
> Now after that what i did is made a C++ program with python embedded
> in it : embed
> Also, i made a python script that imports 'test' and use it, named
>     : etest
> 
> now 'embed' is supposed to import 'etest' and use it.
> 
> 'etest' has a function : 'process',
> 
> which takes an argument which is supposed to be an instance of
> Test::KlassProcessor,
> and it calls its 'process2' member function, so the contents of
> 'etest.py' goes like this :
> 
> def process (kp) :
> 	...
> 	kp.process2 (...)
> #
> 
> now back inside my C++ code of 'embed' program, i imported 'etest',
> and then using
> PyObject_GetAttrString, i got the pointer to 'process' function in it.
> 
> But also, i have made a new class in that C++, which inherits from
> Test::KlassProcessor :
> 
> class MyProcessor : Test::KlassProcessor {
> 	virtual void process2 (...) {
> 		... // redefined
> 	}
> };
> 
> I created an instance of this class, and sent it as argument to the
> 'process' function of
> 'etest', using the following code :
> 
> // Creating instance
> MyProcessor* processor = new MyProcessor ();
> 
> // Getting proper sipWrapperType
> const sipTypeDef* kpTypeDef     = sipFindType ("Test::KlassProcessor");
> PyTypeObject*     kpTypeObject  = sipTypeAsPyTypeObject (kpTypeDef);
> sipWrapperType*   kpWrapperType = reinterpret_cast<sipWrapperType*>
> (kpTypeObject);
> 
> // Wrapping up C++ instance
> PyObject* pyProcessor = sipConvertFromInstance (processor, kpWrapperType,
> NULL);
> 
> // Getting pointer to 'etest.process' function
> PyObject* process = PyObject_GetAttrString (etest, "process");
> 
> // Finally calling 'process'
> PyObject* argTup = Py_BuildValue ("(O)", pyProcessor);
> PyObject_Call (process, argTup, NULL);
> Py_XDECREF (argTup);
> 
> What is happening there that the 'process' function is calling the
> 'process2'
> of the argument. But rather than the 'process2' of my inherited
> 'MyProcessor',
> the 'process2' of its parent class 'Test::KlassProcessor' is being
called.
> 
> I know that i can very well write an extension of MyProcessor and be done
> with
> this problem. But i was just curious that is there any way to pass
inherit
> the SIP-extended class in C++ and then using its instance from python ?

The path your code takes doesn't involve the vtable for KlassProcessor so
your MyProcessor::process2() will not get called.

If your process() function was in C++ then it would call process2() via the
vtable and it would get called.

> Last but not least, i would like to write some examples on using SIP
> which might help beginners learning it. is it ok if i add it into the
wiki
> at
> http://www.diotavelli.net/PyQtWiki ? I am asking this bcoz almost all
> the tutorials there are regarding PyQt or PyKDE... so maybe there is some
> other proper place to post them..

Fine by me - but it's not my Wiki.

> Thanks in advance to anyone who took the time to read my problem :)
> 
> And finally thanks for SIP :)

Phil


More information about the PyQt mailing list