Problem with simple C extension

harold fellermann harold.fellermann at upf.edu
Tue Jun 14 12:58:54 EDT 2005


Am I stupid or what?

I want to implement a very simple extension class in C (as I did
it many times before...) The python equivalent of my class whould
look like:

class physics_DPD :
	def __init__(self,cutoff,friction,noise,dt) :
		self.cutoff = cutoff
		self.friction = friction
		self.noise = noise
		self.dt = dt

That's all fir the start. Simple, heh? My C implementation is
the following:


#include <Python.h>
#include "structmember.h"

// PhysicsDPD instance structure
typedef struct {
   PyObject_HEAD
   double cutoff;
   double friction;
   double noise;
   double dt;
} hyper_PhysicsDPD;


//----------------------------------------------------------------------
// tp_init
//----------------------------------------------------------------------
static int
hyper_PhysicsDPD_init(hyper_PhysicsDPD *self, PyObject *args, PyObject 
*kwds)
{
   if (!PyArg_ParseTuple(args,"ffff",
			&self->cutoff,
			&self->friction,
			&self->noise,
			&self->dt
			))
     return -1;

   printf("%f %f %f 
%f\n",self->cutoff,self->friction,self->noise,self->dt);

   return 1;
}

//----------------------------------------------------------------------
// method table
//----------------------------------------------------------------------
static PyMethodDef hyper_PhysicsDPD_methods[] = {
   {NULL}  /* Sentinel */
};

//----------------------------------------------------------------------
// instance members
//----------------------------------------------------------------------
static PyMemberDef hyper_PhysicsDPD_members[] = {
   {"cutoff", T_DOUBLE, offsetof(hyper_PhysicsDPD,cutoff), 0, "cutoff 
radius"},
   {"friction", T_DOUBLE, offsetof(hyper_PhysicsDPD,friction), 0, 
"friction"},
   {"noise", T_DOUBLE, offsetof(hyper_PhysicsDPD,noise), 0, "noise"},
   {"dt", T_DOUBLE, offsetof(hyper_PhysicsDPD,dt), 0, "time step"},
   {NULL}  /* Sentinel */
};

//----------------------------------------------------------------------
// type structure
//----------------------------------------------------------------------
static PyTypeObject hyper_PhysicsDPDType = {
     PyObject_HEAD_INIT(NULL)
     0,                         /* ob_size */
     "simulation.hyper.physics_DPD",       /* tp_name */
     sizeof(hyper_PhysicsDPD),  /* tp_basicsize */
     0,                         /* tp_itemsize */
     0,                         /* tp_dealloc */
     0,                         /* tp_print */
     0,                         /* tp_getattr */
     0,                         /* tp_setattr */
     0,                         /* tp_compare */
     0,                         /* tp_repr */
     0,                         /* tp_as_number */
     0,                         /* tp_as_sequence */
     0,                         /* tp_as_mapping */
     0,                         /* tp_hash */
     0,                         /* tp_call */
     0,                         /* tp_str */
     0,                         /* tp_getattro */
     0,                         /* tp_setattro */
     0,                         /* tp_as_buffer */
     Py_TPFLAGS_DEFAULT
     | Py_TPFLAGS_BASETYPE ,    /* tp_flags */
     "DPD physics",             /* tp_doc */
     0,                         /* tp_traverse */
     0,                         /* tp_clear */
     0,                         /* tp_richcompare */
     0,                         /* tp_weaklistoffset */
     0,                         /* tp_iter */
     0,                         /* tp_iternext */
     hyper_PhysicsDPD_methods,  /* tp_methods */
     hyper_PhysicsDPD_members,  /* tp_members */
     0,                         /* tp_getset */
     0,                         /* tp_base */
     0,                         /* tp_dict */
     0,                         /* tp_descr_get */
     0,                         /* tp_descr_set */
     0,                         /* tp_dictoffset */
     (initproc)hyper_PhysicsDPD_init, /* tp_init */
     0,                         /* tp_alloc */
     0,                         /* tp_new */
     0,                         /* freefunc tp_free */
     0,                         /* inquiry tp_is_gc */
     0,                         /* PyObject *tp_bases */
     0,                         /* PyObject *tp_mro */
     0,                         /* PyObject *tp_cache */
     0,                         /* PyObject *tp_subclasses */
     0,                         /* PyObject *tp_weaklist */
     0,                         /* destructor tp_del */
};


//----------------------------------------------------------------------
// module hyper
//----------------------------------------------------------------------

static PyMethodDef hyper_methods[] = {
   {NULL}  /* Sentinel */
};

#ifndef PyMODINIT_FUNC  /* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC inithyper(void)
{
   PyObject* m;
   m = Py_InitModule3("hyper", hyper_methods,
		     "Faster C implementation of the underlying physics.");

   hyper_PhysicsDPDType.tp_new = PyType_GenericNew;
   if (PyType_Ready(&hyper_PhysicsDPDType) < 0) return;

   Py_INCREF(&hyper_PhysicsDPDType);
   PyModule_AddObject(m, "physics_DPD", (PyObject 
*)&hyper_PhysicsDPDType);
}


Now, compilation and import works without problem. But I cannot
assign members in the init-call.

 >>> import simulation.hyper.physics_DPD as Physics
 >>> p = Physics(1,2,3,4)
0.000000 0.000000 0.000000 0.000000
 >>> p.friction
5.3049894774131808e-315

I must be blind today. Can anyone see what I am doing wrong
in init???

Thanks a lot!

- harold -


--
A country without army is like a fish without bicycle.
--




More information about the Python-list mailing list