Note that there are some explanatory texts on larger screens.

plurals
  1. POPython C-API Object Allocation‏
    primarykey
    data
    text
    <p>I want to use the new and delete operators for creating and destroying my objects.</p> <p>The problem is python seems to break it into several stages. tp_new, tp_init and tp_alloc for creation and tp_del, tp_free and tp_dealloc for destruction. However c++ just has new which allocates and fully constructs the object and delete which destructs and deallocates the object.</p> <p>Which of the python tp_* methods do I need to provide and what must they do?</p> <p>Also I want to be able to create the object directly in c++ eg "PyObject *obj = new MyExtensionObject(args);" Will I also need to overload the new operator in some way to support this?</p> <p>I also would like to be able to subclass my extension types in python, is there anything special I need to do to support this?</p> <p>I'm using python 3.0.1.</p> <p>EDIT: ok, tp_init seems to make objects a bit too mutable for what I'm doing (eg take a Texture object, changing the contents after creation is fine, but change fundamental aspects of it such as, size, bitdept, etc will break lots of existing c++ stuff that assumes those sort of things are fixed). If I dont implement it will it simply stop people calling __init__ AFTER its constructed (or at least ignore the call, like tuple does). Or should I have some flag that throws an exception or somthing if tp_init is called more than once on the same object?</p> <p>Apart from that I think ive got most of the rest sorted.</p> <pre><code>extern "C" { //creation + destruction PyObject* global_alloc(PyTypeObject *type, Py_ssize_t items) { return (PyObject*)new char[type-&gt;tp_basicsize + items*type-&gt;tp_itemsize]; } void global_free(void *mem) { delete[] (char*)mem; } } template&lt;class T&gt; 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-&gt;tp_basicsize = sizeof(T); t-&gt;tp_itemsize = 0; t-&gt;tp_name = "unknown"; t-&gt;tp_alloc = (allocfunc) global_alloc; t-&gt;tp_free = (freefunc) global_free; t-&gt;tp_new = (newfunc) T::obj_new; t-&gt;tp_dealloc = (destructor)T::obj_dealloc; ... } ...bunch of methods for changing stuff... PyObject *Finalise() { ... } }; template &lt;class T&gt; PyObjectExtension : public PyObject { ... extern "C" static PyObject* obj_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) { void *mem = (void*)subtype-&gt;tp_alloc(subtype, 0); return (PyObject*)new(mem) T(args, kwds) } extern "C" static void obj_dealloc(PyObject *obj) { ~T(); obj-&gt;ob_type-&gt;tp_free(obj);//most of the time this is global_free(obj) } ... }; class MyObject : PyObjectExtension&lt;MyObject&gt; { public: static PyObject* InitType() { ExtensionType&lt;MyObject&gt; extType(); ...sets other stuff... return extType.Finalise(); } ... }; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload