[C++-sig] using a python object that implements a c++ interface in c++

Alexis H. Rivera-Rios ahrivera at yahoo.com
Tue Aug 23 22:04:25 CEST 2005


Hi,

I'm trying to use python to create objects that
implement a given interface and passing them to c++
functions.  This is what I have:
--- test.h ---
template <class A>
class MyFactory
{
public:
	virtual ~MyFactory() {}
	virtual A* CreateA() const = 0;
};

struct Data
{
	int x;
};

The boost::python code:

// Boost Includes
==============================================================
#include <boost/python.hpp>
#include <boost/cstdint.hpp>

// Includes
====================================================================
#include "test.h"

// Using
=======================================================================
using namespace boost::python;

// Declarations
================================================================
namespace  {

typedef MyFactory<Data> Factory1;

struct Factory1Wrap : MyFactory<Data>,
wrapper<MyFactory<Data> >
{
    Data* CreateA() const
    {
        //return
this->get_override("CreateMissile")();
		return call< Data*
>(this->get_override("CreateA").ptr());
    }
};

}// namespace 


// Module
======================================================================
BOOST_PYTHON_MODULE(PysteError)
{
    class_< Data >("Data", init<  >())
        .def(init< const Data& >())
		.def_readwrite("x", &Data::x)
    ;

   class_< Factory1Wrap, boost::noncopyable
>("Factory1", init<  >())
	   .def("CreateA", pure_virtual(&Factory1::CreateA),
return_value_policy<manage_new_object> () )     
    ;

}

The python implementation of the interface:
import PysteError
class PyFactory(PysteError.Factory1):
	def __init__(self):
		pass
	def CreateA(self):
		d = PysteError.Data()
		d.x = 1;
		return d
				 
factory = PyFactory();

The C++ code that tries to get the python object:
// Boost Includes
==============================================================
#include <boost/python.hpp>
#include <boost/cstdint.hpp>
#include <string>
#include "test.h"

using namespace boost::python;

int main (void)
{
	std::string fileName = "test.py";
	std::string loadModule = "execfile('"+fileName+"')";
	std::string factoryName = "factory";
	object factory;

	Py_Initialize(	);

	try {
		object main_module((
		handle<>(borrowed(PyImport_AddModule("__main__"
)))));
		object main_namespace =
main_module.attr("__dict__");

		handle<> ignored((PyRun_String(
			loadModule.c_str()
			, Py_single_input
			, main_namespace.ptr()
			, main_namespace.ptr())
		));
		factory = main_namespace["factory"];
		
		//// IT FAILS HERE ////
		const MyFactory<Data> &ptr = extract<
MyFactory<Data>  >(factory);
		std::auto_ptr<Data> d (ptr.CreateA());

	}
	catch(error_already_set)
	{
		PyErr_Print();
	}

	Py_Finalize();
}

I get the following error:

TypeError: No registered converter was able to produce
a C++ rvalue of type class MyFactory<struct Data> from
this Python object of type PyFactory


Can anybody please explain what does the error mean?
What is the correct way to do this?

Thanks,
Alexis



Programming Tutorial:
In Python: To do this, do this
In Perl: To do this, do this or this or this or this...
In C: To do this, do this, but be careful
In C++: To do this, do this, but don't do this, be careful of this, watch out for this, and whatever you do, don't do this

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 



More information about the Cplusplus-sig mailing list