2010-08-09 5 views
2

Я работаю над созданием расширения python c, но мне трудно найти документацию о том, что я хочу делать. Я в основном хочу создать указатель на cstruct и иметь доступ к этому указателю. Ниже приведен пример кода. Любая помощь будет оценена по достоинству.Доступ к базовой структуре PyObject

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  
} 

ответ

3

Ваш PyArg_ParseTuple не следует использовать формат O но O! (см документацию):

O! (object) [typeobject, PyObject *] 

хранить объект Python в объект C указатель. Это похоже на O, но принимает два аргумента C: первый - это адрес объекта типа Python, второй - это адрес переменной C (типа PyObject *) в , в котором хранится указатель объекта , Если объект Python не имеет нужного типа , TypeError будет поднят.

После того, как вы сделали это, вы знаете, что в теле вашей функцией (PointObject*)point будет правильным и действительным указателем на PointObject, и поэтому его ->my_point будет Point* вы ищете. В обычном формате O вам придется выполнять проверку типов самостоятельно.

Edit: ОП через комментарии запрашивает источник ...:

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

Алекс, я мог получить источник для того, как сделать это, я еще немного потерял. – Pat

+0

ОК, @user, я только что отредактировал свой A, чтобы добавить исходный код по вашему запросу. –

Смежные вопросы