访问的PyObject的基本结构 [英] Accessing the underlying struct of a PyObject

查看:298
本文介绍了访问的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 format O but O! (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 a PointObject, and therefore its ->my_point will be the Point* you seek. With a plain format O 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆