[C++-sig] PyImport_Import problems with a BOOST_PYTHON_MODULE defined module
Peter
python at cityofdreams.com
Thu Sep 2 05:46:16 CEST 2004
I solved the initial import problem by defining a global object
variable and constructing an instance from that, i.e.,
object g_Catcher;
BOOST_PYTHON_MODULE(RuntimeSupport)
{
g_Catcher =
class_<StdoutCatcher>("StdoutCatcher")
.def( "write", &StdoutCatcher::write )
;
}
Then imported the module and created the class instance:
boost::python::str supportModuleName("RuntimeSupport");
handle<> supportModule(
PyImport_Import(supportModuleName.ptr()) );
object catcherObj = g_Catcher();
PySys_SetObject("stdout",catcherObj.ptr());
PySys_SetObject("stderr",catcherObj.ptr());
I'm still having problems with the visibility of modules imported
PyImport_Import. Python code still does not see these modules, so I
have to reimport them in Python.
Regards
Peter
> Thanks to some previous answers plus some intense googling, I've been
> able to use a C++ class to capture stdout and stderr. However, I have
> encountered a problem with PyImport_Import and a module defined with
> BOOST_PYTHON_MODULE.
>
> I created a StdoutCatcher C++ class (in a module named RuntimeSupport)
> and have got to the point where I can use it from within Python ok:
>
> >>> import sys, RuntimeSupport
> >>> sys.stdout = RuntimeSupport.StdoutCatcher()
> >>> sys.stderr = RuntimeSupport.StdoutCatcher()
>
> But my goal is to redirect stdout purely using the C APIs, but I still
> have much to learn and have hit a bit of a wall after experimenting all
> day. I found that PyImport_Import should accomplish what I want, but
> for all my experimenting I just can't get it to work. Below is the code
> and it would be great if anyone could critique my use of boost.python
> and the Python C API, and point out where I have gone wrong. All
> criticism would be very much appreciated.
>
> Building with MS VC++ 6 on w2k, using Python embedded in the app.
>
> //*********************************************************
> class StdoutCatcher
> {
> public:
> StdoutCatcher() { clear(); }
> void write( const std::string& str ) { text_ += str; }
>
> static const std::string& text(void) { return text_; }
> static void clear(void) { text_.erase(); }
>
> private:
> static std::string text_;
> };
> std::string StdoutCatcher::text_;
>
> //*********************************************************
> // Python module
> BOOST_PYTHON_MODULE(RuntimeSupport)
> {
> class_<StdoutCatcher>("StdoutCatcher")
> .def( "write", &StdoutCatcher::write )
> ;
> }
>
> ... initialize everything ...
>
> PyImport_AppendInittab("RuntimeSupport", initRuntimeSupport);
> Py_Initialize();
> mainModule_ = new object(handle<>(borrowed(
> PyImport_AddModule("__main__") ) ) );
> mainNamespace_ = new dict(mainModule_->attr("__dict__") );
>
> ... everything now works ok if just using Python
> ... but I can't get it to work using just API calls,
> ... see below
>
> // import the RuntimeSupport module
> // --> I tried all import ways;
> // PyImport_ImportModuleEx, PyImport_Import,
> // PyImport_ImportModule
> boost::python::str supportModuleName("RuntimeSupport");
> handle<> supportModule(
> PyImport_Import(supportModuleName.ptr()) );
>
> // create an instance of StdoutCatcher
> // --> this bit doesn't work and returns NoneType
> // --> maybe because PyImport failed?
> object catcher = mainNamespace_->get("StdoutCatcher");
>
> // --> is there a better way to check for NoneType
> // than a strcmp?
> PyObject* pObj = catcher.ptr();
> if ( strcmp(pObj->ob_type->tp_name, "NoneType") == 0)
> {
> // ... why isn't StdoutCatcher being found?
> }
> else
> {
> // --> never get to this bit
>
> // create an instance of StdoutCatcher
> object catcherObj = catcher();
>
> // set sys.stdout and sys.stderr to the
> // StdoutCatcher instance
> PySys_SetObject("stdout",catcherObj.ptr());
> PySys_SetObject("stderr",catcherObj.ptr());
> }
>
> ... so the main question is, why can't I import StdoutCatcher using the
> APIs?
>
> Thanks,
> Peter
>
>
>
>
>
> _______________________________________________
> C++-sig mailing list
> C++-sig at python.org
> http://mail.python.org/mailman/listinfo/c++-sig
>
>
More information about the Cplusplus-sig
mailing list