[C++-sig] Python converters for raw pointers: request for help

Michele De Stefano micdestefano at gmail.com
Fri Oct 23 10:38:30 CEST 2009


Hello to everyone.

I'm trying to write "from Python" converters for PETSc objects of the
petsc4py package.
Even if no-one of you uses petsc4py, I think you can help me, if I
explain some basics.
Please, be patient.

I want to make converters for the PETSc Mat type.

Mat is defined as below:

typedef struct _p_Mat*           Mat;

where _p_Mat is a structure whose details are not interesting for my problem.

Now, I managed to make a functioning "to Python converter".

My problem is the "from Python converter".

I made a test function

void print_Mat(Mat m) {
    ... // The implementation is not interesting
};

And I tried to make a "from Python converter" with the code below
(please, look at it ... it's not too long and it's very simple):


struct PETSc_Mat_from_Python {
	
	PETSc_Mat_from_Python() {

		static bool		do_registration(true);
		
		if (do_registration) {
			
			boost::python::converter::registry::push_back(
					&convertible,&construct,boost::python::type_id<Mat>());
			
			do_registration = false;
		}
	}
	
	static void* convertible(PyObject* obj_ptr) {
		
                // In the line below, PyPetscMat_Get takes a PyObject*
as input and returns a Mat
                // (if it succedes) or a PETSC_NULL (if it fails).
This is a function of the petsc4py C API.
                // The ownership of the returned Mat is not
transferred (I think)

		if (PyPetscMat_Get(obj_ptr) == PETSC_NULL) return NULL;
		
		return obj_ptr;
	}
	
	static void construct(PyObject* obj_ptr,
			boost::python::converter::rvalue_from_python_stage1_data* data) {

		void* storage = (
				(boost::python::converter::
				rvalue_from_python_storage<Mat>*)data)->storage.bytes;
		
		data->convertible = storage;
		
                // NOTE: The instruction below does not transfer
ownership, but this is not my problem, for now
		new (storage) Mat(PyPetscMat_Get(obj_ptr));
	}
};


Then, obviously ...

BOOST_PYTHON_MODULE(petsc_ext) {

        ... some not important lines ...

        PETSc_Mat_from_Python(); // Registers the converter
	
	def("print_Mat",print_Mat);
}


The code compiles without errors.
The problem is that when calling "print_Mat" from the Python shell,
the interpreter gives the error:

print_Mat(m)  # where m was previously and correctly built from Python
and it is a Python object containing a Mat

Traceback (most recent call last):
  File "<stdin>", line 1, in ?
Boost.Python.ArgumentError: Python argument types in
    petsc_ext.print_Mat(petsc4py.PETSc.Mat)
did not match C++ signature:
    print_Mat(_p_Mat*)


I tried also to modify "void print_Mat(Mat m)" into "void
print_Mat(const Mat m)" or "void print_Mat(const Mat& m)", but the
result is the same.

I tried also to debug the code, but the debugger does not enter into
the "convertible" method, so I guess there is something wrong that I
can't see.

So may be I am missing something for the process of writing a "from
Python converter" for pointer arguments.

Can anyone help me, please ?


-- 
Michele De Stefano
http://www.linkedin.com/in/micdestefano


More information about the Cplusplus-sig mailing list