[PyQt] SIP and virtual functions

Phil Thompson phil at riverbankcomputing.com
Tue Nov 23 21:47:55 GMT 2010


On Tue, 23 Nov 2010 17:12:01 +0100, Jens Thoms Toerring <jt at toerring.de>
wrote:
> Hi Phil,
> 
> On Tue, Nov 23, 2010 at 02:42:59PM +0000, Phil Thompson wrote:
>> Not every C++ class can be wrapped. SIP often has to create temporary
>> instances which obviously requires support from the underlying C++.
> 
> Thanks for the quick reply! It's a bit unlucky in my case since
> creating public constructors with no arguments or a single int
> argument simply doesn't make sense:-( And can you tell me why
> in some cases a constructor with no argument and in others one
> with an int are used? Without that information I wouldn't even
> know which constructors I have to define (if I find a way to do
> that).

Sorry I don't understand the question.

> BTW, looking at the sipVH_PyFoo_0() function it looks a bit as
> if an instance of A is only created to obtain enough memory for
> an object returned by sipParseResult(). So I'm wondering if the
> constructor call couldn't be avoided when generating the function
> instead in this way:
> 
> A sipVH_PyFoo_0(sip_gilstate_t sipGILState,PyObject *sipMethod)
> {
> 	std::auto_ptr<char> sipRes(new char[sizeof(A)]);
>     PyObject *resObj = sipCallMethod(0,sipMethod,"");
> 
>     if (!resObj || sipParseResult(0,sipMethod,resObj,"H5",sipType_A,
> 	                              reinterpret_cast<A*>(sipRes.get())) < 0)
>         PyErr_Print();
> 
>     Py_XDECREF(resObj);
>     Py_DECREF(sipMethod);
> 
>     SIP_RELEASE_GIL(sipGILState)
> 
> 	return *reinterpret_cast<A*>(sipRes.get());
> }
> 
> As far as I know new() should return memory properly aligned for
> arbitrary objects and using a std::auto_ptr should take care of
> not creating a memory leak . But then I'm not 100% sure if retur-
> ning the content of an auto_ptr is ok, so an alternative might
> be:
> 
> A sipVH_PyFoo_0(sip_gilstate_t sipGILState,PyObject *sipMethod)
> {
> 	char *tmp = sipRes(new char[sizeof(A)]);
>     PyObject *resObj = sipCallMethod(0,sipMethod,"");
> 
>     if (!resObj || sipParseResult(0,sipMethod,resObj,"H5",sipType_A,
> 	                              reinterpret_cast<A*>(tmp)) < 0)
>         PyErr_Print();
> 
>     Py_XDECREF(resObj);
>     Py_DECREF(sipMethod);
> 
>     SIP_RELEASE_GIL(sipGILState)
> 
>     A sipRes = *reinterpret_cast<A*>(tmp);
> 	delete [] tmp;
> 	return sipRes;
> }
> 
> But perhaps that's a stupid idea (especially since I have no
> good knowledge of the innards of the sipParseResult() function).
> It's just an idea I came upon while pondering what's going on;-)

That would probably work, but it relies on there being a public copy ctor
for A. It's a strange API that has a public copy ctor but no other public
ctor.

Phil


More information about the PyQt mailing list