[PyQt] SIP Pointer Confusion

Phil Thompson phil at riverbankcomputing.com
Tue Oct 4 09:38:02 BST 2016


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


More information about the PyQt mailing list