<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<p>
</p>
<div class="moz-text-flowed" style="font-family: -moz-fixed;
font-size: 12px;" lang="x-unicode">Hi
<br>
<br>
I'm trying to create bindings for a class Foo with a constructor
taking a std::function, so basically for
<br>
<br>
typedef std::function<Item*()> ItemFactory;
<br>
Foo( ItemFactory factory, QObject* parent = 0 );
<br>
<br>
in the sip file I'm writing
<br>
<br>
Foo( SIP_PYCALLABLE factory, QObject *parent = 0 );
<br>
%MethodCode
<br>
<br>
// Make sure the callable doesn't get garbage collected, this
is needed because refcount for a1 is 0
<br>
// and the creation function pointer is passed to the metadata
and it needs to be kept in memory.
<br>
Py_INCREF( a0 );
<br>
<br>
Py_BEGIN_ALLOW_THREADS
<br>
<br>
auto factory = [a0]() -> Item *
<br>
{
<br>
Item *result = nullptr;
<br>
SIP_BLOCK_THREADS
<br>
PyObject *s = sipCallMethod( NULL, a0, NULL );
<br>
int state;
<br>
int sipIsError = 0;
<br>
result = reinterpret_cast<Item *>( sipConvertToType(
s, sipType_Item, NULL, SIP_NO_CONVERTORS, &state,
&sipIsError ) );
<br>
SIP_UNBLOCK_THREADS
<br>
return result;
<br>
};
<br>
<br>
sipCpp = new sipFoo( factory, a1 );
<br>
<br>
Py_END_ALLOW_THREADS
<br>
<br>
%End
<br>
<br>
This however does not work, due to
<br>
<br>
error: no matching function for call to ‘Foo::Foo(PyObject*&,
QObject*&)’
<br>
<br>
Any pointers how to do this? Full example code below.
<br>
<br>
Many thanks
<br>
Sandro
<br>
<br>
<br>
-------------- foo.h --------------
<br>
<br>
#ifndef FOO_H
<br>
#define FOO_H
<br>
<br>
#include <functional>
<br>
#include <QObject>
<br>
#include <QVector>
<br>
<br>
<br>
class Item {
<br>
public:
<br>
virtual ~Item() {}
<br>
};
<br>
<br>
class Foo : public QObject
<br>
{
<br>
Q_OBJECT
<br>
public:
<br>
typedef std::function<Item*()> ItemFactory;
<br>
Foo( ItemFactory factory, QObject* parent = 0 );
<br>
~Foo();
<br>
void create();
<br>
<br>
private:
<br>
ItemFactory mFactory;
<br>
QVector<Item *> mItems;
<br>
};
<br>
<br>
#endif // FOO_H
<br>
<br>
<br>
-------------- foo.cpp --------------
<br>
<br>
#include "foo.h"
<br>
<br>
Foo::Foo( ItemFactory factory, QObject *parent )
<br>
: QObject( parent ), mFactory(factory)
<br>
{
<br>
}
<br>
<br>
Foo::~Foo()
<br>
{
<br>
qDeleteAll( mItems );
<br>
}
<br>
<br>
void Foo::create()
<br>
{
<br>
mItems.append(mFactory());
<br>
}
<br>
<br>
<br>
-------------- foo.sip --------------
<br>
<br>
%Module(name=foo,
<br>
keyword_arguments="All")
<br>
<br>
%Import QtCore/QtCoremod.sip
<br>
<br>
class Item
<br>
{
<br>
%TypeHeaderCode
<br>
#include "foo.h"
<br>
%End
<br>
virtual ~Item();
<br>
};
<br>
<br>
class Foo : QObject
<br>
{
<br>
%TypeHeaderCode
<br>
#include "foo.h"
<br>
%End
<br>
public:
<br>
Foo( SIP_PYCALLABLE factory, QObject *parent = 0 );
<br>
%MethodCode
<br>
<br>
// Make sure the callable doesn't get garbage collected, this
is needed because refcount for a1 is 0
<br>
// and the creation function pointer is passed to the metadata
and it needs to be kept in memory.
<br>
Py_INCREF( a0 );
<br>
<br>
Py_BEGIN_ALLOW_THREADS
<br>
<br>
auto factory = [a0]() -> Item *
<br>
{
<br>
Item *result = nullptr;
<br>
SIP_BLOCK_THREADS
<br>
PyObject *s = sipCallMethod( NULL, a0, NULL );
<br>
int state;
<br>
int sipIsError = 0;
<br>
result = reinterpret_cast<Item *>( sipConvertToType(
s, sipType_Item, NULL, SIP_NO_CONVERTORS, &state,
&sipIsError ) );
<br>
SIP_UNBLOCK_THREADS
<br>
return result;
<br>
};
<br>
<br>
sipCpp = new sipFoo( factory, a1 );
<br>
<br>
Py_END_ALLOW_THREADS
<br>
<br>
%End
<br>
~Foo();
<br>
};
<br>
<br>
<br>
</div>
</body>
</html>