我正在寫一個包裝外部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