2012-12-13 93 views
1

所以我有一個GUI程序,有很多「東西」在繼續。我正在添加一個python腳本界面,以便有人可以與此環境進行交互。我使用boost python。所以我的第一件事就是我想創建一個新的模塊。爲簡單起見,現在我只是模塊是世界你好...嵌入在C++中的Python

#include <boost/python.hpp>              

char const* greet() {               
    return "hello, world" ;              
}                    

BOOST_PYTHON_MODULE(cerrnimapi) {            
    boost::python::def("greet", greet) ;           
} 

在我的系統我有一個類,看起來像這樣...

Controller::Controller() {   
    Py_Initialize() ;                

    main_module = boost::python::import("__main__") ;       
    main_namespace = main_module.attr("__dict__") ;        
}                                      

void Controller::execute_script(std::string filename) {      
    try {                   
    boost::python::api::object ignored =           
     boost::python::exec_file(filename.c_str(), main_namespace) ;    
    } catch(boost::python::error_already_set const &) {       
    if (PyErr_ExceptionMatches(PyExc_ZeroDivisionError)) {      
    } else {                  
     PyErr_Print();               
    }                   
    }                    
} 

現在,當我去執行腳本我得到一個錯誤的圖形用戶界面...

Traceback (most recent call last): 
    File "/home/mokon/repository/trunk/python.py", line 1, in <module> 
    import cerrnimapi 
ImportError: No module named cerrnimapi 

所以當然,我構建了一些錯誤。我的構建系統使用自動工具使這裏有涉及到這一點,構建系統的幾件...

在configure.ac:

AM_PATH_PYTHON                 
AC_ARG_VAR([PYTHON_INCLUDE], [Include flags for python, bypassing python-config]) 
AC_ARG_VAR([PYTHON_CONFIG], [Path to python-config])        
AS_IF([test -z "$PYTHON_INCLUDE"], [            
    AS_IF([test -z "$PYTHON_CONFIG"], [           
    AC_PATH_PROGS([PYTHON_CONFIG],            
        [python$PYTHON_VERSION-config python-config],     
        [no],               
        [`dirname $PYTHON`])           
    AS_IF([test "$PYTHON_CONFIG" = no], [AC_MSG_ERROR([cannot find python-config for $PYTHON.])]) 
    ])                    
    AC_MSG_CHECKING([python include flags])          
    PYTHON_INCLUDE=`$PYTHON_CONFIG --includes`          
    AC_MSG_RESULT([$PYTHON_INCLUDE])            
])                    

AC_ARG_VAR([PYTHON_LD], [Linker flags for python, bypassing python-config])  
AS_IF([test -z "$PYTHON_LD"], [             
    AS_IF([test -z "$PYTHON_CONFIG"], [           
    AC_PATH_PROGS([PYTHON_CONFIG],            
        [python$PYTHON_VERSION-config python-config],     
        [no],               
        [`dirname $PYTHON`])           
    AS_IF([test "$PYTHON_CONFIG" = no], [AC_MSG_ERROR([cannot find python-config for $PYTHON.])]) 
    ])                    
    AC_MSG_CHECKING([python linker flags])           
    PYTHON_LD=`$PYTHON_CONFIG --ldflags`           
    AC_MSG_RESULT([$PYTHON_LD])             
]) 

在我的OBJ /目錄Makefile.am ...

pyexec_LTLIBRARIES = cerrnimapi.la            
cerrnimapi_la_SOURCES = ${SRC_DIR}/lib/PythonAPI.cpp        
cerrnimapi_la_LDFLAGS = -avoid-version -module $(PYTHON_LD)      
cerrnimapi_la_CXXFLAGS = $(PYTHON_INCLUDE) 

我的makefile和我的主程序一起構建了共享庫及其obj文件夾。這沒有幫助。我也做了一個make install來安裝cerrnimapi lib到python文件夾中。這沒有幫助。

我也嘗試將PythonAPI.cpp添加到我的主程序源中,但無濟於事。

任何想法?讓我知道什麼額外的信息會有幫助。

+0

另外,更多的,我想想我認爲我做錯了。我不應該只是能夠將我的庫編譯到我的C++程序中,嵌入式python interp將能夠看到符號? –

+0

您的構建過程是否生成名爲「cerrnimapi.so」的共享庫?這就是進口要尋找的東西。至於圖書館中的靜態鏈接,這不是直接鼓勵,但如果你想破解它,這裏有信息:http://mdqinc.com/blog/2011/08/statically-linking-python-with-cython-generated-模塊和 - 包/。 –

回答

1

有些事情要檢查:

  • 運行nm在你的.so文件(這可能是在.libs),以確保您的模塊初始化func被導出。
  • 使您的程序打印出sys.path(使用PyRun_SimpleString)的值以查看期望模塊啓動的位置。如果您只爲解釋器定義模塊,則可能不希望將其安裝在$pyexecdir中。
  • 閱讀Extending Embedded Python文章。你根本不需要構建動態庫,除非你正在嘗試插件體系結構。

款式的一點:你應該嘗試找到$PYTHON_CONFIG外面你的測試對$PYTHON_INCLUDE$PYTHON_LD所以你沒有做的AC_PATH_PROGS兩次:

AM_PATH_PYTHON                 
AC_ARG_VAR([PYTHON_CONFIG], [Path to python-config])        
AS_IF([test -z "$PYTHON_CONFIG"], [           
    AC_PATH_PROGS([PYTHON_CONFIG],            
       [python$PYTHON_VERSION-config python-config],     
       [no],               
       [`dirname $PYTHON`])           
])                    

AC_ARG_VAR([PYTHON_INCLUDE], [Include flags for python, bypassing python-config]) 
AS_IF([test -z "$PYTHON_INCLUDE"], [            
    AC_MSG_CHECKING([python include flags])          
    AS_IF([test "$PYTHON_CONFIG" = no], [AC_MSG_ERROR([cannot find python-config for $PYTHON.])]) 
    PYTHON_INCLUDE=`$PYTHON_CONFIG --includes`          
    AC_MSG_RESULT([$PYTHON_INCLUDE])            
])                    

AC_ARG_VAR([PYTHON_LD], [Linker flags for python, bypassing python-config])  
AS_IF([test -z "$PYTHON_LD"], [             
    AC_MSG_CHECKING([python linker flags])           
    AS_IF([test "$PYTHON_CONFIG" = no], [AC_MSG_ERROR([cannot find python-config for $PYTHON.])]) 
    PYTHON_LD=`$PYTHON_CONFIG --ldflags`           
    AC_MSG_RESULT([$PYTHON_LD])             
]) 
+0

因此,我創建的python api需要訪問我的主應用程序中的模型,因爲它需要與它交互。例如,我有一個關閉該系統的簡單命令。爲此,它抓取一個全局對象並實質上調用它的關閉方法。當然問題是,從.so動態鏈接的文件調用該文件,因此全局爲空。我需要它從主程序訪問。我沒有看到你所指的那篇文章在哪裏 –

+0

任何幫助,將不勝感激。我覺得這是非常基本的...它已經有一段時間了,因爲我不得不擔心這個... –

+0

我鏈接到你的手冊部分顯示瞭如何在你的主程序中定義一個模塊。你根本不需要有.so。要回到你的主程序,看起來你必須傳遞函數指針:http://stackoverflow.com/questions/3454909/sharing-data-with-a-dynamically-loaded-library-dlopen-dlsym。不要這樣做,它會變得混亂。 –