[PyQt] SIP Pointer Confusion

Jay L. jlaura at asu.edu
Tue Oct 4 18:56:01 BST 2016


Phil,

Great direction.  I think that I have working example that uses NumPy C-API
alongside SIP.  This requires that numpy/arrayobject.h be included.  Below
is the method declaration and method code.  I am seeing this get data
allocated to the GPU and other methods return roughly meaningful results (I
have validation to do, etc.).

      void Allocate(int width, int height, int pitch, bool withHost, float
*devMem /In/ = NULL, SIP_PYOBJECT *hostMem /In/ = NULL) /KeywordArgs="All"/;
      %MethodCode
          import_array();
          //Interpret arg5 as a numpy array
          PyObject *hostmem = PyArray_FROM_OTF(a5, NPY_CFLOAT,
NPY_ARRAY_C_CONTIGUOUS | NPY_ARRAY_ALIGNED | NPY_ARRAY_ENSUREARRAY);

          //Check that the above worked and did not return a NULL pointer
          if(hostmem == NULL){
            Py_XDECREF(hostmem);
          }

          //Get a pointer to the data as C-types
          float *x = (float*)PyArray_DATA(hostmem);

          //Call the function
          sipCpp->Allocate(a0, a1, a2, a3, NULL, x);
      %End

I have to dig a bit to see about getting the type dynamically from the
PyObject, but otherwise I think that this is work.

Thanks!
J

On Tue, Oct 4, 2016 at 1:38 AM, Phil Thompson <phil at riverbankcomputing.com>
wrote:

> On 4 Oct 2016, at 5:47 am, Jay L. <jlaura at asu.edu> wrote:
> >
> > I have made some progress on this.  My .sip file now includes:
> >
> >  13       void Allocate(int width, int height, int pitch, bool withHost,
> float *devMem /In/ = NULL, SIP_PYOBJECT hostMem /In/ = NULL);
> >  14       %MethodCode
> >  15         Py_BEGIN_ALLOW_THREADS
> >  16           long length = a0 * a1;
> >  17           a5 = PyFloat_AsDouble(sipConvertToArray(a5, "f", length,
> 0));
> >  18           sipCpp->Allocate(a0, a1, a2, a3, NULL, a5);
> >  19         Py_END_ALLOW_THREADS
> >  20       %End
> >
> > This is, I believe the method that I should be using to grab the
> arguments, operate on the buffer and then pass the arguments on to the C++
> method.
> >
> > As Phil suggested, sipConvertToArray looks like way to go here.  I pass
> in a memoryview (buffer) using ndarray.data.  Using just sipConvertToArray
> results in an error saying that no known conversion from Py_OBJECT* to
> float* is known.
> >
> > Above, I am trying to use PyFloat_AsDouble to make the conversion (that
> I believe needs to be made).  This though, results in the same error.  I
> have checked PyQt, PyKDE, PyQwt, and the QGIS project to see if those
> projects have examples of passing a numpy array in, but must be missing any
> examples.
> >
> > Any additional suggestions much appreciated for getting numpy array data
> passed over to the C++ side.
>
> No, you would use sipConvertToArray() to create a Python object that
> wrapped an array of floats. Here you want to get at the array of floats
> that is wrapped by whatever object numpy is giving you.
>
> You need to understand exactly what ndarray.data is. Don't get confused
> between memoryview objects and objects that support the buffer protocol.
> They are not the same. The former is a wrapper around the latter that gives
> access to the latter from Python.
>
> I would hope (but I don't know) that ndarray implements the buffer
> protocol and that the 'data' attribute is simply a memoryview of the
> ndarray. In which case you would specify the hostMem argument as
> SIP_PYBUFFER and pass in ndarray (and not ndarray.data). In your
> %MethodCode you would then use the standard Python C calls to check that
> the buffer provided has the correct layout and get it's address.
>
> If it's appropriate you should also calculate other arguments (like width
> and height) from the information provided by the buffer protocol rather
> than require the use to pass them in.
>
> Phil
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20161004/b0bdf53a/attachment-0001.html>


More information about the PyQt mailing list