简体   繁体   中英

Python Embedded in C++

So I have a GUI program that has a great deal of "stuff" going on. I am adding a python scripting interface so someone can interact problematically with this environment. I am using boost python. So first thing I have is a new module I want to create. For simplicity right now my module just is hello world...

#include <boost/python.hpp>                                                     

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

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

In my system I have a class that looks like this...

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

Now when I go to execute the script in the GUI I get an error...

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

So of course I am building something wrong. My build system uses autotools so here are a few pieces of that build system that relate to this...

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

In my obj/ dir 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 builds the shared lib and its in the obj folder along with my main program. This doesn't help. I have also done a make install to install the cerrnimapi lib in the python folders. This doesn't help.

I have also tried adding the PythonAPI.cpp to my main programs SOURCES but to no avail.

Any ideas? let me know what additional information would be helpful.

Some things to check:

  • Run nm over your .so file (which might be in .libs ) to make sure your module init func is exported.
  • Make your program print out the value of sys.path (use PyRun_SimpleString) to see where it's expecting your module to turn up. If you're defining modules for your interpreter only, you probably don't want to install them in $pyexecdir .
  • Read the Extending Embedded Python article. You don't really need to build dynamic libraries at all, unless you're trying for a plugin architecture.

A point on style: You should try and find $PYTHON_CONFIG outside of your tests for $PYTHON_INCLUDE and $PYTHON_LD so you're not doing the AC_PATH_PROGS twice:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM