2012-08-23 32 views
2

目标:我想在我的C++代码中使用Boost :: Python库交互式地使用python。 我的目标是改变我在python解释器中定义的一些类的变量。Boost :: Python和函数与变量

该代码附在下面。

问题:我可以在Python接口(即负载hello)中加载库并使其中的对象(obj = hello.World())。我甚至可以访问没有变量的函数(obj.greet()),但是当我想要访问变量函数(obj.Set(“Hello”))时,我得到了内存访问冲突(“访问冲突读取位置0xffffffffffffffff”)。即使这个函数是一个只需要一些字符串的空函数。

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; 
} 

其实这个来自升压:: Python的教程进行一些修改,以使用Python解释器 http://www.boost.org/doc/libs/1_51_0/libs/python/doc/tutorial/doc/html/python/exposing.html

非常感谢

--------------- ------ 编辑 ---------------------

我测试了很多,发现只有字符串输入问题。即char *或int没有问题。 boost python中的字符串有问题吗?

+1

Py_Main()调用看起来可疑的(尽管它可能是无关的崩溃)。如果你删除了PyMain(),'PyRun_SimpleString(“import hello as h; w = h.World(); w.set('abc')\ n”);'产生'访问冲突'。 – jfs

+0

我试过你的建议,并得到错误(有点不同)。关键是当我在set(string msg)中使用字符串并在set函数中设置断点时,msg的值不正确,但如果使用set(char * msg),那么msg就是我从python解释器发送的内容。 - Hesa​​m 6分钟前 – Hesam

+1

你看到什么'void set(string _msg){std :: cerr << _msg <<'\ n'; }'和上面的PyRun_Simple ..调用? – jfs

回答

1

我发现我犯了一个错误,并添加boost_python(.LIB文件)的静态库到链接页面。我不知道它是什么导致,但我删除后,我发现,而不是“boost_python-vc100-mt-1_51.dll”该程序使用“boost_python-vc100-mt-gd-1_51.dll”。

问题已解决,但任何人都可以解释是什么问题?

所有非常感谢帮助

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(); 
} 

How can I start the python console within a program (for easy debugging)?见。

编译:

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

运行:

$ ./main -i 
+0

非常感谢您的回复。我正在使用Visual Studio 2010,只是有字符串输入问题(这实际上困扰着我)。我想也许这与链接器选项MDd和调试模式有关? – Hesam

+1

@Hesam:是的,你可能会使用不兼容的msvcrt dll。调用[ctypes.util.find_msvcrt](http://docs.python.org/library/ctypes.html#ctypes.util.find_msvcrt)来找出你应该使用的库(msvcr90.dll)。特别是malloc/free被称为失败,版本不同 – jfs

+0

我按照你的指示输出了:'msvcr90.dll'。我正在编译x64调试模式。这个DLL可以吗? – Hesam