我正在写一个包装外部C库的Python C扩展。在原有的库有(讨论的缘故T
型)结构,所以我的扩展类看起来是这样的:如何从Python C扩展中访问子类的对象结构体字段?
typedef struct {
PyObject_HEAD
T *cdata;
} TWrapperBase;
我还需要从时间查找指针在Python中的时间,所以我暴露了一个只读字段_cdata
,这是一个cdata
指针作为unsigned long long
(是的,我知道它不是很便携,但现在它已经超出了范围)。
然后,我希望能够增加在Python一些方法,但我不能只将它们附加在C声明的类,所以我继承它并添加我的新方法:
class TWrapper(TWrapperBase):
...
现在,在我的C扩展代码中,我需要一个访问cdata
字段的方法,所以我可以将它传递给库函数。我知道self
不会是TWrapperBase
的实例,而是TWrapper
(此Python版本)。 这样做的正确方法是什么?
static PyObject * doStuff(PyObject *self)
{
T *cdata_ptr;
// How to get a pointer to cdata?
//
// This looks very unsafe to me, do I have any guarantee of
// the subclass memory layout?
// 1. cdata_ptr = ((TWrapperBase*)self)->cdata
//
// This is probably safe, but it seems to be a bit of a hassle
// to query it with a string key
// 2. cdata_ptr = PyLong_AsVoidPtr(PyObject_GetAttrString(self, "_cdata"))
do_important_library_stuff(cdata_ptr);
Py_INCREF(self);
return self;
}
谢谢!
你为什么在做'Py_INCREF(self);'*之后*你做图书馆的东西? –
这就是为什么选项1对你来说看起来不安全? –
我是'INCREF'ing它只是因为它是一个返回类型和返回的对象是被盗的引用。 – wesolyromek