Access the underlying PyObject structure

I am working on creating a python c extension, but it's hard for me to find documentation on what I want to do. I basically want to create a pointer to cstruct and have access to that pointer. The following is sample code. Any help would be appreciated.

typedef struct{ int x; int y; } Point; typedef struct { PyObject_HEAD Point* my_point; } PointObject; static PyTypeObject PointType = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ "point", /*tp_name*/ sizeof(PointObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ 0, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash */ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ "point objects", /* tp_doc */ }; static PyObject* set_point(PyObject* self, PyObject* args) { PyObject* point; if (!PyArg_ParseTuple(args, "O", &point)) { return NULL; } //code to access my_point } 
+2
source share
1 answer

Your PyArg_ParseTuple should not use the O format, but O! (see documents):

 O! (object) [typeobject, PyObject *] 

Saving a Python object to a C pointer object. This is similar to O, but accepts two C arguments: the first is the address of an object of type Python, the second is the address of the C variable (of type PyObject *) that is stored in the object pointer. If the Python object does not have the required type, TypeError is raised.

Once you have done this, you know that in your function the body (PointObject*)point will be the correct and correct pointer to PointObject , and therefore its ->my_point will be the Point* you are looking for. In the normal O format, you will have to do type checking yourself.

Edit : OP in the comments asks for the source ...:

 static PyObject* set_point(PyObject* self, PyObject* args) { PyObject* point; if (!PyArg_ParseTuple(args, "O!", &PointType, &point)) { return NULL; } Point* pp = ((PointObject*)point)->my_point; // ... use pp as the pointer to Point you were looking for... // ... and incidentally don't forget to return a properly incref'd // PyObject*, of course;-) } 
+3
source

All Articles