SIP: Virtual pure method with std::function

Denis Rouzaud denis.rouzaud at gmail.com
Thu Apr 1 11:35:38 BST 2021


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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20210401/b77d91d4/attachment.htm>


More information about the PyQt mailing list