[C++-sig] call_method
Brett Calcott
brett.calcott at paradise.net.nz
Sat Nov 9 02:08:21 CET 2002
Hi all,
(Sorry for the delay in getting back David)
> Have you tried adding a call to
>
> implicitly_convertible<py_agent_ptr,agent_ptr>()
>
Damn. I Should have found that really...
It works fine now. Yay!
However, the example I hacked up displays a weird bug. The virtual function
returns a char const *, and when I subclass this in python and return a
string it throws an error:
ReferenceError: Attempt to return dangling pointer to object of type: char
V:/src/boost_python_test/test>python test.py
...but only if there is a space in the string returned. This must be some
weird side effect. Or returning a char const * from python may just be plain
dodgy. Anyway I thought you might want to know about it.
Note: VC6 SP5 - XP Professional.
Here's the code:
namespace {
class agent
{
public:
agent()
{
}
virtual char const *do_something() const
{
return "agent";
}
virtual ~agent()
{
}
};
typedef boost::shared_ptr<agent> agent_ptr;
typedef std::vector<agent_ptr> agents;
class py_agent : public agent
{
public:
py_agent(PyObject* self) : m_self(self) {}
char const *do_something() const
{
using namespace boost::python;
return call_method<char const*>(m_self, "do_something");
}
PyObject* const m_self;
};
typedef boost::shared_ptr<py_agent> py_agent_ptr;
class engine
{
public:
engine() {}
void add_agent(const agent_ptr &a)
{
m_agents.push_back(a);
}
agents m_agents;
};
}
BOOST_PYTHON_MODULE(simple)
{
using namespace boost::python;
implicitly_convertible<py_agent_ptr,agent_ptr>();
class_<agents>("agents")
.def("__iter__", iterator<agents>())
;
class_<agent, bases<>, agent_ptr>("agent")
.def("do_something", &agent::do_something)
;
class_<agent, bases<>, py_agent_ptr, boost::noncopyable>("py_agent")
.def("do_something", &agent::do_something)
;
class_<engine>("engine", init<>())
.def("add_agent", &engine::add_agent)
.add_property("agents"
, make_getter(&engine::m_agents, return_internal_reference<>()))
;
}
and the python:
import simple
e = simple.engine()
class my_agent(simple.py_agent):
def do_something(self):
# return "my agent here" ******CRASH****
return "my_agent_here" # this is okay
a1 = simple.agent()
a2 = my_agent()
e.add_agent(a1)
e.add_agent(a2)
for a in e.agents:
print a.do_something()
Cheers,
Brett
More information about the Cplusplus-sig
mailing list