2

Goal: I'm trying to use python interactively in my c++ code using Boost::Python library. My goal is to change variables of some class which I have defined in c++ from the python interpreter.

The code is attached below.

Problem: I can load the library in python interface (i.e. load hello) and make an object out of it (obj = hello.World()). I even can access functions without variables ( obj.greet() ) but when I want to access functions with variables (obj.Set("Hello") ) I get memory access violation ("Access violation reading location 0xffffffffffffffff"). Even when that function is an empty function which just takes some string.

struct World
{
    void set(string _msg) {}
    string greet() { return msg; }
    string msg;
};
typedef boost::shared_ptr<World> World_ptr;
BOOST_PYTHON_MODULE(hello)
{
    bp::class_<World, World_ptr>("World")
        .def("greet", &World::greet)
        .def("set", &World::set)
    ;
}
int main(int argc, char **argv)
{
    Py_Initialize();    

    bp::object main = bp::object(bp::handle<>(bp::borrowed(PyImport_AddModule("__main__"))));
    bp::object global(main.attr("__dict__"));
    inithello();
    // Bring up Python interpreter
    Py_Main(argc, argv);

    Py_Finalize();

    return 0;
}

Actually this comes from Boost::Python tutorials with some modification to use Python interpreter http://www.boost.org/doc/libs/1_51_0/libs/python/doc/tutorial/doc/html/python/exposing.html

Many thanks

--------------------- Edit ---------------------

I tested a lot and found out that the problem is only with string inputs. i.e. No problem with char* or int. Is there any problem with strings in boost python?

Roy
  • 65
  • 2
  • 15
  • 40
  • 1
    Py_Main() call looks suspicious (though it might be unrelated to the crash). Does `PyRun_SimpleString("import hello as h; w=h.World(); w.set('abc')\n");` produce 'access violation' if you remove PyMain(). – jfs Aug 23 '12 at 04:15
  • I tried your suggestion and get the error (a little different). The point is when I use string in set(string msg) and make breakpoint inside set function the value of msg is not correct but if I use set(char* msg) the msg is what I sent from python interpreter. – Hesam 6 mins ago – Roy Aug 23 '12 at 04:58
  • 1
    What do you see with `void set(string _msg) { std::cerr << _msg << '\n'; }` and the above PyRun_Simple.. call? – jfs Aug 23 '12 at 05:01
  • The error is: vctools/../dbgdl.cpp. Debug Assertion Failed. Block_Type_Is_Valid(pHead->nBlockUse). By the way I'm using visual studio 2010 (in MDd mode). – Roy Aug 23 '12 at 05:12

2 Answers2

1

I see no errors:

/**
 $ sudo apt-get install libboost-python-dev
 $ ./do
*/
#include <boost/python.hpp>

struct World
{
    void set(std::string msg) { this->msg = msg; }
    std::string greet() { return msg; }
    std::string msg;
};


namespace py = boost::python;

BOOST_PYTHON_MODULE(hello)
{
  py::class_<World>("World")
    .def("greet", &World::greet)
    .def("set", &World::set)
    ;
}

int main(int argc, char* argv[]) {
  Py_Initialize();
  inithello();

  PySys_SetArgv(argc, argv); // use later in Python
  if (PyRun_SimpleString("import hello\n"
                         "planet = hello.World()\n"
                         "planet.set('howdy')\n"
                         "print(planet.greet())\n"

                         // start interactive Python shell if `-i`
                         "import sys\n"
                         "if '-i' in sys.argv:\n"
                         "  import code\n"
                         "  code.interact()\n" //NOTE: namespace may be provided
                         ) < 0)
    return 1; // an exception is raised in Python

  Py_Finalize();
}

See also How can I start the python console within a program (for easy debugging)?.

Compile:

$ c++ main.cpp -o main `python-config --cflags` \
     `python-config --ldflags` -lboost_python

Run:

$ ./main -i
Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • Many thanks for the reply. I'm using Visual Studio 2010 and just have problem with string inputs (which really is bothering me). I think maybe this be related to Linker options MDd and Debug mode?! – Roy Aug 24 '12 at 04:18
  • 1
    @Hesam: yes, you might use incompatible msvcrt dll. Call [ctypes.util.find_msvcrt](http://docs.python.org/library/ctypes.html#ctypes.util.find_msvcrt) to find out what library you should be using (msvcr90.dll). In particular malloc/free are known to fail with different versions – jfs Aug 24 '12 at 12:53
  • I followed your instructions and output was: 'msvcr90.dll'. I'm compiling in x64 debug mode. Is this dll ok? – Roy Aug 24 '12 at 15:45
  • 1
    @Hesam: it tells you what you should use, not what you are actually using (I don't know what VS 2010 uses). And you should install 64-bit version of python. The same for boost. – jfs Aug 24 '12 at 16:32
1

I found that I had made a mistake and added static library of boost_python (.lib file) into the linker page. I'm not sure what It was leading to but after I deleted it I found that instead of "boost_python-vc100-mt-1_51.dll" the program is using "boost_python-vc100-mt-gd-1_51.dll".

Problem is solved, but can anyone explain what was the problem?

Many thanks for all the helps

Roy
  • 65
  • 2
  • 15
  • 40