【问题标题】:Accessing the underlying struct of a PyObject访问 PyObject 的底层结构
【发布时间】:2010-08-09 00:52:23
【问题描述】:

我正在创建一个 python c 扩展,但很难找到关于我想要做什么的文档。我基本上想创建一个指向 cstruct 的指针并能够访问该指针。示例代码如下。任何帮助将不胜感激。

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    
}

【问题讨论】:

    标签: python c pointers structure


    【解决方案1】:

    您的PyArg_ParseTuple 不应使用O 格式,而应使用O!(请参阅文档):

    O! (object) [typeobject, PyObject *]
    

    将 Python 对象存储在 C 对象中 指针。这与 O 类似,但 接受两个 C 参数:第一个是 Python 类型对象的地址, 第二个是C的地址 变量(PyObject* 类型)到 对象指针存储的位置。如果 Python 对象没有 必需类型,引发 TypeError。

    一旦你这样做了,你就会知道在你的函数体中(PointObject*)point 将是一个正确且有效的指向PointObject 的指针,因此它的->my_point 将是你寻找的Point*。使用纯格式 O 您必须自己进行类型检查。

    编辑:cmets中的OP要求来源...:

    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;-)
    }
    

    【讨论】:

    • Alex,我能得到如何做到这一点的来源吗?我还是有点迷茫。
    • 好的,@user,我刚刚编辑了我的 A 以根据您的要求添加源代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-02
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    • 2023-03-11
    • 2018-09-19
    • 2010-09-10
    相关资源
    最近更新 更多