From: John M. <mcf...@gm...> - 2010-12-11 01:01:36
|
Hi, I am wrapping a C++ template class for python. The C++ class defines a constructor and that gets wrapped fine. However, I would like to add an additional constructor for use from python. I've tried this two ways, but I run into a problem with each. The first approach I tried was to use %extend and define an alternate constructor that accepts a PyObject*. This actually does work, but the problem is I can't incorporate any type checking on the argument. I can put in code to check for an incorrect type, set the python error string, and return NULL, but the NULL return value doesn't get propagated all the way through the wrappers and the result is that incorrect argument types don't actually trigger an error when used from python. The second approach I tried was to use %pythonprepend to try and prepend some python code to implement the alternate constructor and do error checking. The problem with this is that the python code is not getting inserted, and I think it's because I'm using a template class (I could successfully use pythonprepend with a non-template class). Here is some (shortened) example code to demonstrate what I tried in each case: // Here is how I tried the prepend. This worked with a non-template class... %pythonprepend Matrix<double>::Matrix<double>(int,int) %{ # additional code... %} template <class T> class Matrix{ T *data; public: Matrix(int m, int n) {} } // Instantiate template: %template(DMatrix) Matrix<double>; // Here is how I tried extending an alternate constructor with C++ code. // This works except for the type checking. The NULL return value doesn't get // propagated through all of the Swig wrapper code %extend Matrix<double> { Matrix<double>(PyObject* o) { // Do type check and try to set an error on failure: if ([incorrect type]) { PyErr_SetString(PyExc_TypeError,"Error string"); return NULL; } else return new Matrix<double>(2,2); // Or something appropriate based on PyObject *o } }; // ------End code Hopefully it's somewhat clear what I'm trying to do. Essentially I would like to add an additional constructor that allows a Python data structure (such as a sequence type) to be used as the constructor argument -- this works with %extend except for my type checking. The other problem is that I can't seem to get %pythonprepend to work with the template class. Any help is much appreciated, or maybe there's just a better way of doing this? John |