On Sat, 13 Feb 2010 18:34:58 +0100, "Diez B. Roggisch" <[email protected]> wrote: > Hi, > > wrapping happily away a 3D-engine, I encounter the following problem: > > >>> import irrlicht > >>> core = irrlicht.irr.core > >>> q = core.quaternion() > >>> q.toEuler() > python(3701) malloc: *** error for object 0x474b70: double free > *** set a breakpoint in malloc_error_break to debug > (0.0, -0.0, 0.0) > > > This is the declaration of toEuler in .sip: > > void toEuler(irr::core::vector3df& euler /Out/) const; > > As you can see, it's supposed to modify a passed vector in place. > However, I declared vectors to be converted from & to tuples, by this > code mapping: > > %MappedType irr::core::vector3df > { > %TypeHeaderCode > #include <vector3d.h> > %End > > %ConvertFromTypeCode > if (!sipCpp) > return PyTuple_New(0); > irr::core::vector3df *v = (irr::core::vector3df *)sipCpp; > return PyTuple_Pack(3, > PyFloat_FromDouble(v->X),PyFloat_FromDouble(v->Y),PyFloat_FromDouble(v->Z)); > %End > > %ConvertToTypeCode > if (sipIsErr == NULL) { > if(PySequence_Check(sipPy) && PySequence_Length(sipPy) == 3) { > for(int j = 0; j < 3; j++) { > PyObject *v = PySequence_GetItem(sipPy, j); > if(!PyFloat_Check(v) && !PyInt_Check(v)) { > return false; > } > } > return true; > } > return false; > } > if (sipPy == Py_None) { > *sipCppPtr = NULL; > return 0; > } > > irr::core::vector3df *v = new irr::core::vector3df(); > PyErr_Clear(); > irr::core::vector3df &t = *v; > if(PyArg_ParseTuple(sipPy, "fff", &t.X, &t.Y, &t.Z)) { > *sipCppPtr = v; > return 1; > } else { > delete v; > *sipIsErr = 1; > return 0; > } > %End > }; > > Looking at the generated code, it seems to me it is perfectly fine - it > creates a new vector instance, passes that in, converts it to a tuple, > and deletes it. > > extern "C" {static PyObject *meth_irr_core_quaternion_toEuler(PyObject > *, PyObject *);} > static PyObject *meth_irr_core_quaternion_toEuler(PyObject *sipSelf, > PyObject *sipArgs) > { > int sipArgsParsed = 0; > > { > irr::core::vector3df * a0; > irr::core::quaternion *sipCpp; > > if > (sipParseArgs(&sipArgsParsed,sipArgs,"B",&sipSelf,sipType_irr_core_quaternion,&sipCpp)) > { > PyObject *sipResult; > a0 = new irr::core::vector3df(); > > sipCpp->toEuler(*a0); > > sipResult = > sipConvertFromNewType(a0,sipType_irr_core_vector3df,NULL); > delete a0; > > return sipResult; > } > } > > /* Raise an exception if the arguments couldn't be parsed. */ > sipNoMethod(sipArgsParsed,sipName_quaternion,sipName_toEuler); > > return NULL; > } > > > I don't understand the behavior - anything I miss?
Which version of SIP? I think this is fixed in SIP v4.10. Unrelated... There is a memory leak in your %ConvertToTypeCode as PySequence_GetItem() returns a new reference to the item. However you should use the PyTuple functions anyway (which don't return a new reference) because you are using PyArg_ParseTuple() to do the conversion. Phil _______________________________________________ PyQt mailing list [email protected] http://www.riverbankcomputing.com/mailman/listinfo/pyqt
