[PyQt] sip: add new annotation for specifying ownership of results of virtual methods

Phil Thompson phil at riverbankcomputing.com
Fri Sep 21 15:28:20 BST 2012


On Mon, 3 Sep 2012 22:27:41 +0200, Mathias.Born at gmx.de wrote:
> Hi Phil,
> 
> I've come across a case which I think deserves its own function
annotation.
> This is the proplem:
> 
> I'm embedding Python code into a C++ app. There are two wrapped classes:
> 
> class Netlister
> {
>       virtual ~Netlister();
>       ...
> };
> 
> and
> 
> class Project
> {
>       virtual ~Project();
>       ...
>       virtual NetLister* netLister(const std::string& netListText)
const;
> };
> 
> In Python, I have ("ltse_app" is the C++ app exposed as module)
> 
> 
> class LTspiceNetLister(ltse_app.NetLister):
>       ...
> 
> and
> 
> class Project(ltse_app.Project):
>       ...
>       def netLister(self, netListText):
>             return LTspiceNetLister()
> 
> 
> First, I call a Python function which gives me an instance of the Python
> class "Project". Then (in C++, using its wrapper), I call its method
> "netLister",
> which returns an instance of "LTspiceNetLister". The goal is to use
> this instance on the C++ side via its wrapper. Thus, ownership should be
> with C++.
> 
> But there is no corresponding annotation for the sip file. I have to
> provide
> a "%VirtualCatcherCode":
> 
> virtual NetLister* netLister(const std::string& netListText /NoCopy/)
> const;
> %VirtualCatcherCode
>         PyObject *resObj = sipCallMethod(0, sipMethod, "D",
>         const_cast<std::string*>(&a0), sipType_std_string, NULL);
>         sipIsErr = !resObj || sipParseResult(0, sipMethod, resObj, "H0",
>         sipType_NetLister, &sipRes) < 0;
>         if (!sipIsErr) sipTransferTo(resObj, Py_None);
>         Py_XDECREF(resObj);
> %End
> 
> Note how I use "sipTransferTo(resObj, Py_None);" to bind the Python
object
> to the C++ instance.
> I'm basically asking for something like the "Factory" annotation which
> does just that.
> 
> "Factory" tells sip that a wrapped C++ function creates a new object
that
> will be owned by the
> Python side. I'd like to have another annotation which tells sip that
the
> Python implementation
> of a class method creates a new object that will be owned by the C++
side.

The documentation for /Factory/ is wrong (now fixed in hg). It effectively
does...

    sipTransferTo(resObj, selfObj);

...in the virtual catcher (where selfObj) is the class's self object (the
Project instance in this case). You are using Py_None but I don't think it
would make a difference.

Would this remove your use case for sipTransfer(obj, Py_None)?

Phil


More information about the PyQt mailing list