[SIP] SIP_PYCALLABLE in constructor

Sandro Mani <[email protected]>
Newsgroups gmane.comp.python.pyqt-pykde
Message-ID <[email protected]>
Hi

I'm trying to create bindings for a class Foo with a constructor taking 
a std::function, so basically for

     typedef std::function<Item*()> ItemFactory;
     Foo( ItemFactory factory, QObject* parent = 0 );

in the sip file I'm writing

     Foo( SIP_PYCALLABLE factory, QObject *parent = 0 );
     %MethodCode

     // Make sure the callable doesn't get garbage collected, this is 
needed because refcount for a1 is 0
     // and the creation function pointer is passed to the metadata and 
it needs to be kept in memory.
     Py_INCREF( a0 );

     Py_BEGIN_ALLOW_THREADS

     auto factory = [a0]() -> Item *
     {
       Item *result = nullptr;
       SIP_BLOCK_THREADS
       PyObject *s = sipCallMethod( NULL, a0, NULL );
       int state;
       int sipIsError = 0;
       result = reinterpret_cast<Item *>( sipConvertToType( s, 
sipType_Item, NULL, SIP_NO_CONVERTORS, &state, &sipIsError ) );
       SIP_UNBLOCK_THREADS
       return result;
     };

     sipCpp = new sipFoo( factory, a1 );

     Py_END_ALLOW_THREADS

     %End

This however does not work, due to

error: no matching function for call to ‘Foo::Foo(PyObject*&, QObject*&)’

Any pointers how to do this? Full example code below.

Many thanks
Sandro


-------------- foo.h --------------

#ifndef FOO_H
#define FOO_H

#include <functional>
#include <QObject>
#include <QVector>


class Item {
public:
     virtual ~Item() {}
};

class Foo : public QObject
{
     Q_OBJECT
   public:
     typedef std::function<Item*()> ItemFactory;
     Foo( ItemFactory factory, QObject* parent = 0 );
     ~Foo();
     void create();

   private:
     ItemFactory mFactory;
     QVector<Item *> mItems;
};

#endif // FOO_H


-------------- foo.cpp --------------

#include "foo.h"

Foo::Foo( ItemFactory factory, QObject *parent )
   : QObject( parent ), mFactory(factory)
{
}

Foo::~Foo()
{
   qDeleteAll( mItems );
}

void Foo::create()
{
     mItems.append(mFactory());
}


-------------- foo.sip --------------

%Module(name=foo,
         keyword_arguments="All")

%Import QtCore/QtCoremod.sip

class Item
{
%TypeHeaderCode
#include "foo.h"
%End
     virtual ~Item();
};

class Foo : QObject
{
%TypeHeaderCode
#include "foo.h"
%End
   public:
     Foo( SIP_PYCALLABLE factory, QObject *parent = 0 );
     %MethodCode

     // Make sure the callable doesn't get garbage collected, this is 
needed because refcount for a1 is 0
     // and the creation function pointer is passed to the metadata and 
it needs to be kept in memory.
     Py_INCREF( a0 );

     Py_BEGIN_ALLOW_THREADS

     auto factory = [a0]() -> Item *
     {
       Item *result = nullptr;
       SIP_BLOCK_THREADS
       PyObject *s = sipCallMethod( NULL, a0, NULL );
       int state;
       int sipIsError = 0;
       result = reinterpret_cast<Item *>( sipConvertToType( s, 
sipType_Item, NULL, SIP_NO_CONVERTORS, &state, &sipIsError ) );
       SIP_UNBLOCK_THREADS
       return result;
     };

     sipCpp = new sipFoo( factory, a1 );

     Py_END_ALLOW_THREADS

     %End
     ~Foo();
};

_______________________________________________
PyQt mailing list    [email protected]
https://www.riverbankcomputing.com/mailman/listinfo/pyqt
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.