[PyQt] Pointer Attribute

Jay L. jlaura at asu.edu
Wed Oct 26 18:39:55 BST 2016


Phil,

Thanks for the pointers.  Here is the resultant code.

I have added the check for length and am now allocating the h_data array on
the heap.  I have not added error check for any previous array, but the
point is appreciated.

In the below code, I am segfaulting on the sipConvertToType call and am not
sure why.  The sipTypePoint definition is the lowest code block.  I do not
have any TypeCode defined for the SiftPoint, but all of the types are
standard so I think custom code is not needed there?


The small debug block (commented out) is working as a replacement for the
sipConvertToType call.

Thanks for any insight,
J


    // HOST DATA
    SiftPoint *h_data
    {
        %GetCode
            size_t size = sipCpp->numPts;
            PyObject *l = PyList_New(sipCpp->numPts);
            for (size_t i = 0; i < size; ++i){
                SiftPoint *sp = new SiftPoint(sipCpp->h_data[i]);
                PyObject *p = sipConvertFromType((void*)(sp),
sipType_SiftPoint, NULL);
                PyList_SetItem(l, i, p);
            }
            return l;
        %End

        %SetCode
        size_t length = PyList_Size(sipPy);
        //Check that a PyList has been passed in.
        if (length == -1){
          PyErr_SetString(PyExc_TypeError,
                          "A non-empty list is of SiftPoints is required.");
          sipErr = -1;
        }

        SiftPoint *array_of_points = (SiftPoint *)malloc(sizeof(SiftPoint)
* length);

        //Check that all of the elements of the list are convertable.
        for (size_t i=0; i < length; ++i){
          if (!sipCanConvertToType(PyList_GET_ITEM(sipPy, i),
                                   sipType_SiftPoint, SIP_NOT_NONE)){
              PyErr_SetString(PyExc_ValueError,
                              "Unable to convert element to SiftPoint
object.");
              sipErr = -1;
          }else{
            printf("Processing point: %i\n", i);
            PyObject *sp = PyList_GetItem(sipPy, i);
            SiftPoint *siftpoint = (SiftPoint *)sipConvertToType(sp,

 sipType_SiftPoint,
                                                                 NULL,

 SIP_NOT_NONE,
                                                                 NULL,
                                                                 0);

            //Debug to create a new SiftPoint
            //SiftPoint *siftpoint = new SiftPoint;
            //siftpoint->xpos = i;
            array_of_points[i] = *siftpoint;
          }
        }

        for (int i = 0;i < length;++i){
          printf("XPOS: %f\n", array_of_points[i].xpos);
        }
        return 0;
        %End
    };


// HOST DATA
    SiftPoint *h_data
    {
        %GetCode
            size_t size = sipCpp->numPts;
            PyObject *l = PyList_New(sipCpp->numPts);
            for (size_t i = 0; i < size; ++i){
                SiftPoint *sp = new SiftPoint(sipCpp->h_data[i]);
                PyObject *p = sipConvertFromType((void*)(sp),
sipType_SiftPoint, NULL);
                PyList_SetItem(l, i, p);
            }
            return l;
        %End

        %SetCode
        size_t length = PyList_Size(sipPy);
        //Check that a PyList has been passed in.
        if (length == -1){
          PyErr_SetString(PyExc_TypeError,
                          "A non-empty list is of SiftPoints is required.");
          sipErr = -1;
        }

        SiftPoint *array_of_points = (SiftPoint *)malloc(sizeof(SiftPoint)
* length);

        //Check that all of the elements of the list are convertable.
        for (size_t i=0; i < length; ++i){
          if (!sipCanConvertToType(PyList_GET_ITEM(sipPy, i),
                                   sipType_SiftPoint, SIP_NOT_NONE)){
              PyErr_SetString(PyExc_ValueError,
                              "Unable to convert element to SiftPoint
object.");
              sipErr = -1;
          }else{
            printf("Processing point: %i\n", i);
            PyObject *sp = PyList_GetItem(sipPy, i);
            SiftPoint *siftpoint = (SiftPoint *)sipConvertToType(sp,

 sipType_SiftPoint,
                                                                 NULL,

 SIP_NOT_NONE,
                                                                 NULL,
                                                                 0);

            //Debug to create a new SiftPoint
            //SiftPoint *siftpoint = new SiftPoint;
            //siftpoint->xpos = i;
            array_of_points[i] = *siftpoint;
          }
        }

        for (int i = 0;i < length;++i){
          printf("XPOS: %f\n", array_of_points[i].xpos);
        }
        return 0;
        %End
    };

On Wed, Oct 26, 2016 at 1:21 AM, Phil Thompson <phil at riverbankcomputing.com>
wrote:

> On 26 Oct 2016, at 5:32 am, Jay L. <jlaura at asu.edu> wrote:
> >
> > Made a bit more progress I think.  The below is building but crashing
> when trying to convert from the Python Obj to a SiftPoint.
>
> ...to an array of SiftPoints. This wasn't clear in your original post.
>
> > The %GetCode returns what I am expecting - a Python list of SiftPoint
> objects.  The SiftPoint has been wrapped.  The %SetCode is seg. faulting on
> sipConvertToType.
> >
> > Within the %GetCode, I do not believe I have access to sipTransferObj or
> sipIsErr.
> >
> > Two questions:
> >
> > 1) Is this the intended use of %GetCode and %SetCode?  Should I be using
> another directive?
> >
> > 2) In the SetCode block, how does one go about converting a list of
> class instances into a C++ pointer?  Is this code heading down the right
> path?
> >
> > Thanks!
> >
> >     SiftPoint *h_data
> >     {
> >         %GetCode
> >             size_t size = sipCpp->numPts;
> >             PyObject *l = PyList_New(sipCpp->numPts);
> >             for (size_t i = 0; i < size; ++i){
> >                 SiftPoint *sp = new SiftPoint(sipCpp->h_data[i]);
> >                 PyObject *p = sipConvertFromType((void*)(sp),
> sipType_SiftPoint, NULL);
> >                 PyList_SetItem(l, i, p);
> >             }
> >             return l;
> >         %End
> >
> >         %SetCode
> >         size_t length = PyList_GET_SIZE(sipPy);
>
> You can't assume that you will get a list. You should use PyList_Size()
> and raise a TypeError if it returns a negative length.
>
> >         for (int i=0; i < length; ++i){
> >
> >         if (!sipCanConvertToType(PyList_GET_ITEM(sipPy, i),
> >                                  sipType_SiftPoint, SIP_NOT_NONE))
> >             return 0;
> >         }
> >
> >         printf("So far so good\n");
> >         sipCpp->numPts = length;
> >
> >         // Set the length of the h_data
> >         SiftPoint h_data[length];
>
> The array must be on the heap.
>
> >         sipCpp->h_data = h_data;
>
> You should consider what happens to any previous array.
>
> >
> >         for (size_t i=0; i < length; ++i){
> >             PyObject *sp  = PyList_GetItem(sipPy, i);
> >
> >             SiftPoint *sif = reinterpret_cast<SiftPoint
> *>(sipConvertToType(sp,
> >
>    sipType_SiftPoint,
> >
>    NULL,
> >
>    SIP_NOT_NONE,
> >
>    NULL, 0));
> >             h_data[i] = *sif;
> >         }
> >         %End
>
> Phil
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20161026/1b236ad2/attachment-0001.html>


More information about the PyQt mailing list