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