SIP: Virtual pure method with std::function
Julien Cabieces
julien.cabieces at oslandia.com
Tue Apr 6 13:27:47 BST 2021
Hi Denis,
> For the sake of clarity, you might want to filter out what is specific to
> QGIS syntax, mainly all the SIP_* macros.
> The sipify script is a QGIS internal and not known further.
Indeed, I try to remove all the QGIS specifics, but I miss the SIP_*
macros.
Regards,
Julien
> Hi Julien,
>
> For the sake of clarity, you might want to filter out what is specific to
> QGIS syntax, mainly all the SIP_* macros.
> The sipify script is a QGIS internal and not known further.
>
>
> On Thu, 1 Apr 2021, 11:58 Julien Cabieces, <julien.cabieces at oslandia.com>
> wrote:
>
>>
>> Hi,
>>
>> I would like to define an interface (abstract class) where one method is
>> pure virtual and takes a std::function as a parameter.
>>
>> I have this in my C++ header
>>
>> ```
>> class MyInterface
>> {
>> public:
>>
>> #ifndef SIP_RUN
>> virtual MyObject *doThings( const QString &filePath, const QUrl &url,
>> const std::function<void ( const QString &
>> )> &errorCallback = {} ) = 0 ;
>> #else
>> virtual MyObject *doThings( const QString &filePath, const QUrl &url,
>> SIP_PYCALLABLE / AllowNone / ) = 0;
>> % MethodCode
>> {
>> Py_BEGIN_ALLOW_THREADS
>>
>> sipCpp->MyInterface::doThings( *a0, *a1, [a2]( const QString &
>> error )
>> {
>> SIP_BLOCK_THREADS
>> Py_XDECREF( sipCallMethod( NULL, a2, "D", &error, sipType_QString,
>> NULL ) );
>> SIP_UNBLOCK_THREADS
>> } );
>>
>> sipRes = sipCpp;
>>
>> Py_END_ALLOW_THREADS
>> }
>> % End
>> #endif
>> ```
>>
>> and this in the corresponding sip file
>>
>> ```
>> class MyInterface
>> {
>>
>> %TypeHeaderCode
>> #include "myinterface.h"
>> %End
>> public:
>>
>> virtual MyObject *doThings( const QString &filePath, const QUrl &url,
>> SIP_PYCALLABLE / AllowNone / ) = 0;
>> %MethodCode
>> {
>> Py_BEGIN_ALLOW_THREADS
>>
>> sipCpp->MyInterface::doThings( *a0, *a1, [a2]( const QString &
>> error )
>> {
>> SIP_BLOCK_THREADS
>> Py_XDECREF( sipCallMethod( NULL, a2, "D", &error, sipType_QString,
>> NULL ) );
>> SIP_UNBLOCK_THREADS
>> } );
>>
>> sipRes = sipCpp;
>>
>> Py_END_ALLOW_THREADS
>> }
>> %End
>>
>> };
>> ```
>>
>> I end up with the following compilation errors
>>
>> ```
>> error: non-virtual member function marked 'override' hides virtual member
>> function
>> ::MyObject* doThings(const ::QString&,const ::QUrl&,PyObject *)
>> SIP_OVERRIDE;
>>
>> hidden overloaded virtual function 'MyInterface::doThings' declared here:
>> type mismatch at 3rd parameter ('const std::function<void (const QString
>> &)> &' vs 'PyObject *' (aka '_object *'))
>> virtual MyObject *doThings( const QString &filePath, const QUrl
>> &url,
>> ^
>> error: allocating an object of abstract class type 'sipMyInterface'
>> sipCpp = new sipMyInterface();
>> ^
>> note: unimplemented pure virtual method 'doThings' in 'sipMyInterface'
>> virtual MyObject *doThings( const QString &filePath, const QUrl &url,
>> ```
>>
>> The errors make sense to me because the sip doThings version has not the
>> same signature than the original Cpp one (Callable vs std::function) but
>> I fail to understand how to fix this.
>>
>> Kind regards,
>> Julien
>>
More information about the PyQt
mailing list