访问PyObject的底层结构体
我正在创建一个Python的C扩展,但在寻找相关文档时遇到了困难。我基本上想创建一个指向C结构的指针,并能够访问这个指针。下面是示例代码。任何帮助都将不胜感激。
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
}
1 个回答
3
你的 PyArg_ParseTuple
不应该使用格式 O
,而应该用 O!
(具体可以参考文档):
O! (object) [typeobject, PyObject *]
这个格式是用来在C语言中存储一个Python对象的指针。它和
O
类似,但需要两个C语言参数:第一个是Python类型对象的地址,第二个是一个C语言变量的地址(类型是PyObject*
),这个变量用来存储对象指针。如果传入的Python对象类型不对,就会抛出一个类型错误(TypeError)。
一旦你这样做了,你就可以确定在你函数的主体中,(PointObject*)point
会是一个正确有效的指向 PointObject
的指针,因此它的 ->my_point
就是你想要的 Point*
。如果用普通的格式 O
,你就得自己检查类型了。
编辑:提问者在评论中询问源代码...:
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;-)
}