Help with C API

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Nick Jacobson

    Help with C API

    In the Python Cookbook, Luther Blisset wrote a very useful class with
    the Python C API. It takes a Python list of elements and copies it
    member by member into a C array.

    Here it is, (slightly modified by me):

    static PyObject *totaldoubles(P yObject *self, PyObject *args) {
    PyObject *seq, *item, *fitem;
    double *dbar, result;
    int i, seqlen;

    if (!PyArg_ParseTu ple(args, "O", &seq)) return NULL;
    seq = PySequence_Fast (seq, "argument must be iterable");
    if (!seq) return NULL;

    seqlen = PySequence_Fast _GET_SIZE(seq);
    dbar = malloc(seqlen * sizeof(double)) ;
    if (!dbar) { Py_DECREF(seq); return NULL; }

    for (i=0; i < seqlen; i++) {
    item = PySequence_Fast _GET_ITEM(seq, i);
    if (!item) { Py_DECREF(seq); free(dbar); return NULL; }
    fitem = PyNumber_Float( item);
    if (!fitem) { Py_DECREF(seq); free(dbar); return NULL; }
    dbar[i] = PyFloat_AS_DOUB LE(fitem);
    Py_DECREF(fitem );
    }

    Py_DECREF(seq);
    result = total(dbar, seqlen); /*call a C function using this array*/
    free(dbar);
    return Py_BuildValue(" d", result);
    }

    I'd like to do the reverse: take an C array (say, with 100 elements)
    and copy its elements into a Python list. But I don't know where to
    start...there's no PySequence_Fast _INSERT or even PySequence_Inse rt
    function, for example. Can I create an empty list in the API or
    should I just pass one in from Python?

    Can someone please help with this? Thanks in advance!!

    --Nick
  • vincent wehren

    #2
    Re: Help with C API

    Nick Jacobson wrote:
    ....[color=blue]
    > I'd like to do the reverse: take an C array (say, with 100 elements)
    > and copy its elements into a Python list. But I don't know where to
    > start...there's no PySequence_Fast _INSERT or even PySequence_Inse rt
    > function, for example. Can I create an empty list in the API or
    > should I just pass one in from Python?
    >
    > Can someone please help with this? Thanks in advance!!
    >
    > --Nick[/color]

    http://docs.python.org/api/listObjects.html is probably a good start

    Regards,
    Vincent Wehren




    Comment

    • Nick Jacobson

      #3
      Re: Help with C API

      vincent wehren <vincent@visual trans.de> wrote in message news:<c6vfmv$gr q$1@news1.tilbu 1.nb.home.nl>.. .[color=blue]
      > Nick Jacobson wrote:
      > ...[color=green]
      > > I'd like to do the reverse: take an C array (say, with 100 elements)
      > > and copy its elements into a Python list. But I don't know where to
      > > start...there's no PySequence_Fast _INSERT or even PySequence_Inse rt
      > > function, for example. Can I create an empty list in the API or
      > > should I just pass one in from Python?
      > >
      > > Can someone please help with this? Thanks in advance!!
      > >
      > > --Nick[/color]
      >
      > http://docs.python.org/api/listObjects.html is probably a good start
      >
      > Regards,
      > Vincent Wehren[/color]


      Thank you!

      This is what I ended up writing:

      static PyObject *ex_arytopylist (PyObject *self, PyObject *args) {
      PyObject *seq = NULL, *fitem = NULL;
      double dbar[] = { 1, 2, 3 };
      int i, seqlen = sizeof(dbar) / sizeof(double);

      seq = PyList_New(0);
      if (!seq) return NULL;

      for (i=0; i < seqlen; i++) {
      fitem = PyFloat_FromDou ble(dbar[i]);
      if (!fitem) { Py_DECREF(seq); return NULL; }
      if (PyList_Append( seq, fitem))
      { Py_DECREF(fitem ); Py_DECREF(seq); return NULL; }
      Py_DECREF(fitem );
      }
      return Py_BuildValue(" O", seq);
      }

      My only question is, since PyList_New(0) and Py_BuildValue both
      increment the ref count of seq, is it garbage collected properly? Or
      perhaps I should just write:

      return seq;

      Thanks!

      Comment

      • Nick Jacobson

        #4
        Re: Help with C API

        I don't think I'm stating my question clearly. :(

        Say I create a list in my C function:
        seq = PyList_New(0);
        Then append some numbers to it, whatever.

        Then, when I return from the C function and want to use that list in
        my Python code, do I have to increment its refcount:
        return Py_BuildValue(" O", seq);

        Or do I leave it alone and say:
        return seq;

        Thanks in advance.

        Comment

        • John E. Barham

          #5
          Re: Help with C API

          "Nick Jacobson" wrote:[color=blue]
          > I don't think I'm stating my question clearly. :(
          >
          > Say I create a list in my C function:
          > seq = PyList_New(0);
          > Then append some numbers to it, whatever.
          >
          > Then, when I return from the C function and want to use that list in
          > my Python code, do I have to increment its refcount:
          > return Py_BuildValue(" O", seq);
          >
          > Or do I leave it alone and say:
          > return seq;
          >
          > Thanks in advance.[/color]

          Grepping through the modules shipped w/ Python seems to suggest that you
          should just return it since calling PyList_New() returns a new reference.
          See for example its use in the strop module (http://tinyurl.com/25s4e) which
          does something similar to what you describe.

          HTH,

          John


          Comment

          Working...