访问的PyObject的基本结构 [英] Accessing the underlying struct of a PyObject
问题描述
我的工作创造一个Python C扩展,但我有困难是什么我想做的事情查找文档。基本上,我想创建一个指向一个cstruct并能够有指针访问。样品code如下。任何帮助将是AP preciated。
typedef结构{
INT X;
诠释Ÿ;
}点;typedef结构{
PyObject_HEAD
点* my_point;
} PointObject;静态PyTypeObject PointType = {
PyObject_HEAD_INIT(NULL)
0,/ * ob_size * /
点,/ * * 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 * /
点对象/ * * tp_doc /
};静态的PyObject * set_point(*的PyObject自我,*的PyObject参数)
{
*的PyObject点; 如果(PyArg_ParseTuple(参数,O,&安培;!点))
{
返回NULL;
} // code访问my_point
}
您 PyArg_ParseTuple
不应该使用格式为: 0
但 0
(见文档):
0! (对象)typeobject,的PyObject *]
在C对象存储Python对象
指针。这类似于0,但
需要两个C参数:第一个是
一个Python类型对象的地址,
第二个是C的地址
变量(的类型的PyObject *)转换成
该对象的指针被存储。如果
Python的对象不具备
所需的类型,类型错误时引发。
块引用>一旦你这样做,你知道,在你的函数体
(PointObject *)点
将是一个正确的,有效的指针PointObject
,因此,其- > my_point
将是点*
你寻求。与普通的格式为:0
你必须做的类型检查自己。修改:在注释OP询问源...
静态的PyObject *
set_point(*的PyObject自我,*的PyObject参数)
{
*的PyObject点; 如果(PyArg_ParseTuple(参数,啊!,&安培;!PointType,&安培;点))
{
返回NULL;
} 点* PP =((PointObject *)点) - GT; my_point; // ...使用PP作为指针指向你要找的人... // ...顺带不要忘记返回正确incref'd
//的PyObject *,当然;-)
}I am working on creating a python c extension but am having difficulty finding documentation on what I want to do. I basically want to create a pointer to a cstruct and be able to have access that pointer. The sample code is below. 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 }
解决方案Your
PyArg_ParseTuple
should not use formatO
butO!
(see the docs):O! (object) [typeobject, PyObject *]
Store a Python object in a C object pointer. This is similar to O, but takes two C arguments: the first is the address of a Python type object, the second is the address of the C variable (of type PyObject*) into which the object pointer is stored. If the Python object does not have the required type, TypeError is raised.
Once you've done that, you know that in your function's body
(PointObject*)point
will be a correct and valid pointer to aPointObject
, and therefore its->my_point
will be thePoint*
you seek. With a plain formatO
you'd have to do the type checking yourself.Edit: the OP in a 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;-) }
这篇关于访问的PyObject的基本结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!