[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