[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