[Tutor] can I pass a "structure" to a C function to init a C struct?

Michael P. Reilly arcege@shore.net
Thu, 16 Sep 1999 19:29:42 -0400 (EDT)


> A new question:
> I'm trying this:
> 1) create something similar to C structure with a number of fields say
> 3 fields: a, b, c.
> a will hold integer value
> b will hold a string
> c will hold a float
> 2) Python script will pass this to a C function called
> initStruct through a wrapper function.
> 3)initStruct will initalise its a global structure according to a,b,and
> c. its global structure also contains three fields: i,j,k. i being an
> integer, j a string,, c a float. But they are C type.
> 4) it will return the values to python script
> 5) python script will know how to convert it back and display on screen
> 
> Can anyone tell me what is teh best way to do that? Is that possible???

You will want to look at the "struct" module which encodes data as a
byte array (which is how a C struct is laid out in memory).

Since you don't say what the integer is, I'll assume it is a long. Also
you do not specify what the "string" is; is it a character array or a
pointer to a char?  Let's say that it is a character array.

  >>> import struct
  >>> fmt = "l20sf"
  >>> data = struct.pack(fmt, a, b, c)
  >>> print data
  '\377\000\000\000knights who say ni\000\000\320\017I@'
  >>> print struct.unpack(fmt, data)
  (255, 'knights who say ni\000\000', 3.14159011841)

Then in the C function, overlay the resulting string as a pointer to
the struct you want.  When converting the data back, you need to deal
with the null characters ('\000') in the unpacked string.

    struct b_struct {
      int a;
      char b[20];
      float c;
    } *b;
    PyObject *string_from_python;
    if (PyString_Size(string_from_python) != sizeof(struct b_struct)) {
      PyErr_SetString(PyExc_AssertionError, "Given string not a good size");
      return NULL;
    }
    b = (struct b_struct *)PyString_AsString(string_from_python);
    printf("%d\n%s\n%f\n", b->a, b->b, b-c);

Pointers will be more difficult since references are always
dereferenced in Python.  To handle pointers, you will need to write a C
function.

  -Arcege

-- 
------------------------------------------------------------------------
| Michael P. Reilly, Release Engineer | Email: arcege@shore.net        |
| Salem, Mass. USA  01970             |                                |
------------------------------------------------------------------------