Setting a C-structure from Python

Armin Steinhoff Armin at Steinhoff_de
Sun Jul 9 07:55:52 EDT 2000


In article <3967F70C.17A90288 at seatech.fau.edu>, Benoit says...
>
>I think I find out where the bug was.
>Thanks Armin !
>
>Why this C extension didn't work ?
>
>>
>>  static PyObject * test_setstruct(PyObject * self, PyObject * args) {
>>  PyObject * string_from_python;
>>
>>  if (!PyArg_ParseTuple(args,"S",&string_from_python)) return NULL;
>>
>>  example= (examplestruct *) PyString_AsString(string_from_python);
>> Py_DECREF(string_from_python);
>>  print_struct();
>>
>>  Py_INCREF(Py_None);
>>  return Py_None;
>>  }
>
>Simply because the  "example"  pointer  points to memory owned by
>string_from_python it point to internal data which is actually part of the
>string object.
>When I "decref "   string_from_python, its reference counter becomes 0, and
>the string object is deleted.
>So  "example" points to something wrong in memory.

"example" is always initialized in the context of test_setstruct() ... so it
can't be the reason for your trouble.

As long as "example" points to memory owned by your process ... you will read
probabbly garbage, but it will not produce a SIGSEV.

If you use a different variable for the second call of struct.pack/test_API
all seems to be working well ... but the interpreter is already corrupted.
You can see it if you terminate the interpreter with Ctrl-D ... -> it leads to a
SIGSEV.

I believe the real point is that you can't apply the "S" format to a "string
buffer" which contains binary zeros. IMHO it corrupts the interpreter.

I have changed your code in the following way:

 static PyObject * test_setstruct(PyObject * self, PyObject * args)
 {
 //PyObject * string_from_python;

 char * string_from_python;
 int len;

// if (!PyArg_ParseTuple(args,"S",&string_from_python)) return NULL;
 if (!PyArg_ParseTuple(args,"s#",&string_from_python, &len)) return NULL;

// example= (examplestruct *) PyString_AsString(string_from_python);
 example= (examplestruct *) string_from_python;

// Py_DECREF(string_from_python);
 print_struct();

 Py_INCREF(Py_None);
 return Py_None;
 }

Regards

Armin




More information about the Python-list mailing list