我想使用 new 和 delete 运算符来创建和销毁我的对象。
问题是python似乎把它分成了几个阶段。tp_new、tp_init 和 tp_alloc 用于创建,tp_del、tp_free 和 tp_dealloc 用于销毁。然而 c++ 只有 new 分配和完全构造对象和 delete 破坏和释放对象。
我需要提供哪些 python tp_* 方法,它们必须做什么?
我还希望能够直接在 C++ 中创建对象,例如“PyObject *obj = new MyExtensionObject(args);” 我是否还需要以某种方式重载 new 运算符来支持这一点?
我也希望能够在 python 中对我的扩展类型进行子类化,我需要做些什么来支持这一点吗?
我正在使用 python 3.0.1。
编辑:好的,tp_init 似乎使对象对于我正在做的事情来说有点太可变了(例如,获取一个 Texture 对象,在创建后更改内容很好,但是更改它的基本方面,例如大小、bitdept 等会破坏许多现有的 c++ 东西都假设这些东西是固定的)。如果我不实现它,它只会阻止人们在构造后调用 __init__ (或者至少忽略调用,就像元组一样)。或者,如果 tp_init 在同一个对象上被多次调用,我是否应该有一些引发异常或其他东西的标志?
除此之外,我想我已经把剩下的大部分都整理好了。
extern "C"
{
//creation + destruction
PyObject* global_alloc(PyTypeObject *type, Py_ssize_t items)
{
return (PyObject*)new char[type->tp_basicsize + items*type->tp_itemsize];
}
void global_free(void *mem)
{
delete[] (char*)mem;
}
}
template<class T> class ExtensionType
{
PyTypeObject *t;
ExtensionType()
{
t = new PyTypeObject();//not sure on this one, what is the "correct" way to create an empty type object
memset((void*)t, 0, sizeof(PyTypeObject));
static PyVarObject init = {PyObject_HEAD_INIT, 0};
*((PyObject*)t) = init;
t->tp_basicsize = sizeof(T);
t->tp_itemsize = 0;
t->tp_name = "unknown";
t->tp_alloc = (allocfunc) global_alloc;
t->tp_free = (freefunc) global_free;
t->tp_new = (newfunc) T::obj_new;
t->tp_dealloc = (destructor)T::obj_dealloc;
...
}
...bunch of methods for changing stuff...
PyObject *Finalise()
{
...
}
};
template <class T> PyObjectExtension : public PyObject
{
...
extern "C" static PyObject* obj_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds)
{
void *mem = (void*)subtype->tp_alloc(subtype, 0);
return (PyObject*)new(mem) T(args, kwds)
}
extern "C" static void obj_dealloc(PyObject *obj)
{
~T();
obj->ob_type->tp_free(obj);//most of the time this is global_free(obj)
}
...
};
class MyObject : PyObjectExtension<MyObject>
{
public:
static PyObject* InitType()
{
ExtensionType<MyObject> extType();
...sets other stuff...
return extType.Finalise();
}
...
};