2012-12-13 4 views
1

Итак, у меня есть программа GUI, в которой много «вещей». Я добавляю интерфейс сценариев python, чтобы кто-то мог взаимодействовать с этой средой. Я использую boost python. Итак, первое, что у меня есть, это новый модуль, который я хочу создать. Для простоты теперь мой модуль просто привет мир ...Python Embedded in C++

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

Теперь, когда я иду, чтобы выполнить сценарий GUI я получаю сообщение об ошибке ...

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

Так что, конечно, я строю что-то неправильно. Моя система сборки использует Autotools так вот несколько частей этой сборки системы, которые относятся к этому ...

В 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])             
]) 

В моем объекте/реже 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) 

My makefile создает общую библиотеку lib и ее в папке obj вместе с моей основной программой. Это не помогает. Я также сделал make install для установки cerrnimapi lib в папках python. Это не помогает.

Я также попытался добавить PythonAPI.cpp в свои основные программы SOURCES, но безрезультатно.

Любые идеи? сообщите мне, какая дополнительная информация была бы полезной.

+0

Также тем более, что я думаю об этом я Думаю, я делаю это неправильно. Должен ли я просто иметь возможность скомпилировать мою библиотеку в моей программе на C++, встроенный интерпретатор python сможет видеть символы? –

+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

Итак, для создания api python, который я создаю, требуется доступ к модели в моем основном приложении, так как он должен взаимодействовать с ним. Например, у меня есть простая команда, которая отключает эту систему.Для этого он захватывает глобальный объект и по существу вызывает его метод shutdown. Проблема, конечно, в том, что это вызов из динамически связанного файла .so и, таким образом, глобальное значение null. Мне нужно это для доступа из основной программы. Я не видел, где в этой статье вы ссылались слишком –

+0

Любая помощь была бы оценена. Я чувствую, что это что-то действительно базовое ... Это было давно, так как мне пришлось беспокоиться об этом ... –

+0

В разделе руководства, которое я связал с вами, показано, как определить модуль внутри вашей основной программы. Вам вообще не нужно иметь .so вообще. Чтобы перезвонить в вашу основную программу, похоже, что вам нужно передать указатели функций: http://stackoverflow.com/questions/3454909/sharing-data-with-a-dynamically-loaded-library-dlopen-dlsym. Не делай этого, он становится грязным. –