2012-08-23 33 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