Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在自定义嵌入式Python对象中存储指针_Python_C_Python 2.7_Pointers - Fatal编程技术网

如何在自定义嵌入式Python对象中存储指针

如何在自定义嵌入式Python对象中存储指针,python,c,python-2.7,pointers,Python,C,Python 2.7,Pointers,根据教程,我已经在C中创建了一个自定义Python类型。在我的C语言中,我收到一个指向结构的指针,我希望能够从Python中获取并设置结构中的值,而无需复制它。即 a = myObject.x() # gets the x value in the struct. 或 但是,我看不到如何在python对象中存储指针 我当前的对象定义目前只是python网站上的基本对象实现 typedef struct { PyObject_HEAD myStruct *s; } KeyObje

根据教程,我已经在C中创建了一个自定义Python类型。在我的C语言中,我收到一个指向结构的指针,我希望能够从Python中获取并设置结构中的值,而无需复制它。即

a = myObject.x() # gets the x value in the struct.

但是,我看不到如何在python对象中存储指针

我当前的对象定义目前只是python网站上的基本对象实现

typedef struct {
    PyObject_HEAD
    myStruct *s;
} KeyObject;

static PyTypeObject KeyType = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "ckb.Key",             /* tp_name */
    sizeof(KeyObject), /* 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 */
    "Key objects",           /* tp_doc */
};

static PyMethodDef key_methods[] = {
    {NULL}  /* Sentinel */
};
下面是一个示例(cbk.c),它可以作为此任务的主干:

#包括“external.h”
#包括“Python.h”
#定义模块名称“ckb”
#定义密钥\u类\u名称“密钥”
/*
typedef结构InnerStruct_标记{
int x;
}内部结构;
//*/
typedef结构KeyObject_标记{
皮尤头
InnerStruct*内部;
}键对象;
静态PyObject*键\u新建(PyTypeObject*类型、PyObject*参数、PyObject*kwds){
关键对象*自我;
self=(KeyObject*)类型->tp_alloc(类型,0);
if(self!=NULL){
//self->inner=(InnerStruct*)calloc(1,sizeof(Key));
self->internal=getExternalPtr(1234);//不要在这里分配,从外部库获取指针
如果(自->内部==NULL){
Py_DECREF(self);
返回NULL;
}
}
返回(PyObject*)self;
}
静态无效键\u解除锁定(键对象*自身){
//自由(自我->内部);
delExternalPtr(self->internal);//使用外部dellocation函数(可选)
Py_类型(self)->tp_-free((PyObject*)self);
}
静态PyObject*Key_getX(KeyObject*self,void*closure){
从long(self->inner->x)返回PyInt_;
}
静态int Key_setX(KeyObject*self,PyObject*value,void*closure){
如果(值==NULL){
PyErr_SetString(PyExc_TypeError,“无法删除“x”);
返回-1;
}
如果(!PyInt_检查(值)){
PyErr_SetString(PyExc_TypeError,“'x'值必须是int”);
返回-1;
}
self->inner->x=((PyIntObject*)值)->ob;
返回0;
}
静态PyGetSetDef密钥\u getsets[]={
{“x”,(getter)Key_getX,(setter)Key_setX,“x”,NULL},
{NULL}//Sentinel
};
静态PyTypeObject键类型={
PyVarObject\u HEAD\u INIT(NULL,0)
MOD_NAME“.”KEY_CLASS_NAME,/*tp_NAME*/
sizeof(KeyObject),/*tp_basicsize*/
0,/*tp\u itemsize*/
(析构函数)键_dealloc,/*tp_dealloc*/
0,/*tp_打印*/
0,/*tp\u getattr*/
0,/*tp_setattr*/
0,/*tp\u比较*/
0,/*tp_repr*/
0,/*tp\U作为\U编号*/
0,/*tp\u作为\u序列*/
0,/*tp_作为映射*/
0,/*tp_散列*/
0,/*tp\u调用*/
0,/*tp_str*/
0,/*tp_getattro*/
0,/*tp_setattro*/
0,/*tp作为缓冲区*/
Py_TPFLAGS_默认值|
Py_TPFLAGS_BASETYPE,/*tp_flags*/
键类名称“对象”/*tp\U文档*/
0,/*tp\u导线测量*/
0,/*tp_清除*/
0,/*tp_*/
0,/*tp_弱偏移*/
0,/*tp_iter*/
0,/*tp_iternext*/
0,/*tp_方法*/
0,/*tp_成员*/
Key\u getset,/*tp\u getset*/
0,/*tp_基*/
0,/*tp_dict*/
0,/*tp\u descr\u get*/
0,/*tp\u descr\u集*/
0,/*tp\u偏移量*/
0,/*tp_init*/
0,/*tp_alloc*/
键为新,/*tp键为新*/
};
#定义键检查精确(op)((op)->ob_类型==&键检查类型)
静态PyMethodDef模块_方法[]={
{NULL}//Sentinel
};
PyMODINIT_FUNC initckb(无效){
PyObject*m;
if(PyType\u Ready(&Key\u Type)<0)
返回;
m=Py_InitModule3(MOD_名称、module_方法、,
MOD_NAME”:创建扩展类型(“KEY_CLASS_NAME”)的示例模块;
Py_增量(&键类型);
PyModule_AddObject(m,键类名称,(PyObject*)和键类型);
}
注释

  • 为清晰起见,已重命名(重新组织)现有结构名称/成员
  • 内部结构只有一个构件(x),这足以说明问题
  • 一切都依赖于页面上的(问题中也提到了这一点)
  • 由于包装器对象(键)包含指针(内部),为了避免每次访问它们时都检查它们是否为NULL:
    • 添加了一个初始化它们的构造函数(Key_new-相当于Python中的u new)
    • 还添加了一个析构函数(Key_dealloc-Python中等效的_del__)-它的作用正好相反-以避免内存泄漏(这只是前面的一个项目符号结果)
  • 通过Key_getX、Key_setX函数访问InnerStruct的x成员(注意它们在Key_getset中引用):
    • 来自Python的内部x成员将由key_instance.x访问,因为它是一个key instance属性
      • 这种方法比使用getter(get_x())和setter(set_x(value))更有意义,而且更像python
      • 但是,如果首选getter/setter方式,则应该稍微修改Key_getX、Key_setX签名(我认为删除最后一个参数就可以了),并且它们应该在Key_方法中引用-这应该指定给KeyType作为tp_方法(也在上面的网页中描述)
    • 在向InnerStruct添加新成员时,只需要复制和调整为x完成的内容(当然,如果有些函数看起来太相似的话)
      typedef struct {
          PyObject_HEAD
          myStruct *s;
      } KeyObject;
      
      static PyTypeObject KeyType = {
          PyVarObject_HEAD_INIT(NULL, 0)
          "ckb.Key",             /* tp_name */
          sizeof(KeyObject), /* 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 */
          "Key objects",           /* tp_doc */
      };
      
      static PyMethodDef key_methods[] = {
          {NULL}  /* Sentinel */
      };