[C++-sig] C++ object reference passed to Python trouble...

Tucker, Steve Steve.Tucker at coair.com
Mon Sep 24 18:38:20 CEST 2007


I am having trouble passing a reference of a C++ instance to my Python
script? At first I was able to pass a simple string to the script but
then wanted to pass a C++ object reference and that's were things got
ugly? I am using Visual Studio 2005 and Python 2.5 and Boost 1.34.

 

My code compiles fine and executes up until the 

 

call<void>(pyFunc, obj);

 

code is called. By stepping into the "shared_ptr_to_python.hpp" an
exception is thrown on line 23

else

        return converter::registered<shared_ptr<T>
const&>::converters.to_python(&x);

 

I have tried using a raw pointer, but read it was highly suggested not
to do this!!! So I wrapped the class pointer in a boost::shared_ptr, is
this correct?

 

At first I got this error message -

 

"Unhandled exception at 0x7c812a5b in cpp_python.exe: Microsoft C++
exception: boost::python::error_already_set at memory location
0x0012f900.."

 

Then stripped out actual message using some brilliant code listed in the
forum and got - 

 

"TypeError: No to_python (by-value) converter found for C++ type: class
boost::shared_ptr<class Host>"

 

 Below is my C++ and Python code...

 

"py_connection.pyd" Code

 

class Host

{

public:     

      Host(): _greetVal("Hello"){}

      ~Host(){}

      std::string greet(void){return _greetVal;}

      void set_greet(std::string value){_greetVal = value; _greetVal +=
" good to see you.";}

 

private:

      std::string _greetVal;

};

 

BOOST_PYTHON_MODULE(py_connection)

{

class_<Host>("Host")

            .def("greet", &Host::greet)

            .def("set_greet", &Host::set_greet)

            ;

}

 

-------------------------------------------------------------------

EXE Code ".cpp" file-

 

typedef boost::shared_ptr<Host> spHost;

 

template <class T>

void CallPyFunc(PyObject* pyFunc, T obj)

{

      try

      {

            // ERROR here in shared_ptr_to_python.hpp Line 23

            call<void>(pyFunc, obj);

      }

      catch (error_already_set&)

      {

            PyObject *type, *value, *traceback;

            PyErr_Fetch(&type, &value, &traceback);

            PyErr_Restore(type, value, traceback);

            PyErr_Print();

            PyErr_Restore(type, value, traceback);

            throw;

      }

}

 

int main(int argc, char *argv[])

{

      spHost host(new Host());      

      host->set_greet("Gidday");

 

      Py_Initialize();

 

      PyObject* pyMod = PyImport_ImportModule("parser_util");

      PyObject* pyFunc = PyObject_GetAttrString(pyMod,
"PrintObjectValue");

 

      CallPyFunc(pyFunc, host);

      

      Py_DECREF(pyMod);

      Py_DECREF(pyFunc);

 

      Py_Finalize();

 

      return 0;

}

 

Parser_util.py

 

import py_connection

 

def PrintObjectValue(o):

print o.greet()

o.set_greet("Py Hello")

 

Can you see if I am passing the value correctly so that my Python code
is able to alter the reference? I need to alter it in Python and have it
reflected when the C++ code executes again?

 

I have read a lot about wrapping the C++ object but still don't see my
error. The more I look the more I find that there are many complex
solutions that are sometimes unreadable or understandable. I would love
to find a simple (less complex) solution to passing a C++ object
reference to Python and back but I am not seeing it? 

 

Regards,

--Steve.

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20070924/057ba18f/attachment.htm>


More information about the Cplusplus-sig mailing list