M
matt.keyes
Hey all,
i'm trying to create an application that both embeds and extends python
through boost. i've got a rough framework up and running, but now that
i'm finally to the python part i'm having troubles.
Here's a rough run-down of my code:
Base class (pure):
template<class commandtype>
InputHandler
{
public:
/*...*/
virtual void Enter(commandtype *pOutput) = 0;
};
Derived class:
class PythonInputHandler : public InputHandler<std::string>
{
public:
PythonInputHandler(PyObject *pSelf) : m_pSelf(pSelf) {}
PythonInputHandler(const PythonInputHandler &rhs)
: InputHandler<std::string>(rhs) //doesn't really do anything
, m_pSelf(rhs.m_pSelf)
{
if(m_pSelf)
Py_XINCREF(m_pSelf);
}
virtual ~PythonInputHandler() {Py_XDECREF(m_pSelf);}
//overriden pure function:
virtual void Enter(std::string *pOutput)
{
//this is where the nasty heap crash comes in, more below
*pOutput = call_method<std::string>(m_pSelf, "Enter");
}
}
BOOST_PYTHON_MODULE(PyInputHandler)
{
class_<InputHandler<std::string>, PythonInputHandler,
boost::noncopyable>("PythonInputHandler");
}
Now, when the executable runs, this happens:
if( PyImport_AppendInittab( "PyInputHandler", initPyInputHandler ) ==
-1 )
throw runtime_error("blah");
Py_Initialize();
PyObject *pInit = PyImport_ImportModule("Python.MyTest");
if(pInit == NULL)
//...error handling
PythonInputHandler *pHandler = new
PythonInputHandler(call_method<PythonInputHandler>(pInit,
"CreateInputHandler"));
std::string sTest;
pHandler->Enter(&sTest); //big heap crash
Py_XDECREF(pInit);
/*...*/
Here is the Python code:
from PyInputHandler import *
class PyLogonHandler(PythonInputHandler):
def Enter(Output):
return "Welcome from Python!"
def CreateInitialHandler():
return PyLogonHandler()
Now then, if i change "Welcome from Python!" to a shorter string, like
"Hiya!", then it works, no error. As it stands, i get a
_BLOCK_TYPE_IS_VALID error in what looks like the destructor of the
std::string during the *pOutput = call_method... portion of the code
(i'm assuming the destructor before the assignment to pOutput occurs).
However, in the destructor, i do see the data consisting of "Welcome
from Python!"
Now i'm also a complete noob to boost and python. i've only been
working on this for about 5 hours or so (the python side of things at
any rate), so any tips to improve what i'm doing in addition to helping
with this error is greatly appreciated. i'm finding it difficult to
find some boost.python tutorials that are comprehensive enough. If you
can't tell, i'm trying to expose a version of my InputHandler class to
python so that it can be overriden and created from scripts instead of
being hard-coded into the C++.
Thanks for the help!!!!
i'm trying to create an application that both embeds and extends python
through boost. i've got a rough framework up and running, but now that
i'm finally to the python part i'm having troubles.
Here's a rough run-down of my code:
Base class (pure):
template<class commandtype>
InputHandler
{
public:
/*...*/
virtual void Enter(commandtype *pOutput) = 0;
};
Derived class:
class PythonInputHandler : public InputHandler<std::string>
{
public:
PythonInputHandler(PyObject *pSelf) : m_pSelf(pSelf) {}
PythonInputHandler(const PythonInputHandler &rhs)
: InputHandler<std::string>(rhs) //doesn't really do anything
, m_pSelf(rhs.m_pSelf)
{
if(m_pSelf)
Py_XINCREF(m_pSelf);
}
virtual ~PythonInputHandler() {Py_XDECREF(m_pSelf);}
//overriden pure function:
virtual void Enter(std::string *pOutput)
{
//this is where the nasty heap crash comes in, more below
*pOutput = call_method<std::string>(m_pSelf, "Enter");
}
}
BOOST_PYTHON_MODULE(PyInputHandler)
{
class_<InputHandler<std::string>, PythonInputHandler,
boost::noncopyable>("PythonInputHandler");
}
Now, when the executable runs, this happens:
if( PyImport_AppendInittab( "PyInputHandler", initPyInputHandler ) ==
-1 )
throw runtime_error("blah");
Py_Initialize();
PyObject *pInit = PyImport_ImportModule("Python.MyTest");
if(pInit == NULL)
//...error handling
PythonInputHandler *pHandler = new
PythonInputHandler(call_method<PythonInputHandler>(pInit,
"CreateInputHandler"));
std::string sTest;
pHandler->Enter(&sTest); //big heap crash
Py_XDECREF(pInit);
/*...*/
Here is the Python code:
from PyInputHandler import *
class PyLogonHandler(PythonInputHandler):
def Enter(Output):
return "Welcome from Python!"
def CreateInitialHandler():
return PyLogonHandler()
Now then, if i change "Welcome from Python!" to a shorter string, like
"Hiya!", then it works, no error. As it stands, i get a
_BLOCK_TYPE_IS_VALID error in what looks like the destructor of the
std::string during the *pOutput = call_method... portion of the code
(i'm assuming the destructor before the assignment to pOutput occurs).
However, in the destructor, i do see the data consisting of "Welcome
from Python!"
Now i'm also a complete noob to boost and python. i've only been
working on this for about 5 hours or so (the python side of things at
any rate), so any tips to improve what i'm doing in addition to helping
with this error is greatly appreciated. i'm finding it difficult to
find some boost.python tutorials that are comprehensive enough. If you
can't tell, i'm trying to expose a version of my InputHandler class to
python so that it can be overriden and created from scripts instead of
being hard-coded into the C++.
Thanks for the help!!!!