オブジェクトの作成と破棄に new および delete 演算子を使用したいと考えています。
問題は、python がいくつかの段階に分かれているように見えることです。tp_new、tp_init、および tp_alloc は作成用であり、tp_del、tp_free、および tp_dealloc は破棄用です。ただし、c++ には、オブジェクトを割り当てて完全に構築する new と、オブジェクトを破棄して割り当てを解除する delete しかありません。
どの python tp_* メソッドを提供する必要があり、何をする必要がありますか?
また、「PyObject *obj = new MyExtensionObject(args);」など、C++ でオブジェクトを直接作成できるようにしたいと考えています。これをサポートするには、何らかの方法で 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();
}
...
};