2012-02-14 13 views
7

Estoy usando Boost.Python para incrustar un intérprete en mi ejecutable de C++ y ejecutar algunos scripts preescritos. Lo tengo funcionando para que pueda llamar funciones en el archivo python, pero el código python que quiero usar importa archivos externos y estas importaciones fallan porque 'no hay un módulo nombrado'. Si ejecuto el script directamente desde Python, todo funciona como se esperaba.Cómo funciona la importación con Boost.Python desde dentro de los archivos de python

Así que mi pregunta es ¿cuál es la forma correcta de importar módulos en scripts de Python que se ejecutan a través de enlaces C++?

C++ Code: Código Python

#include "boost/python.hpp" 

int main(int argc, char** argv) 
{ 
    try 
    { 
    Py_Initialize(); 
    boost::python::object test = boost::python::import("__main__"); 
    boost::python::object testDict = test.attr("__dict__"); 
    boost::python::exec_file("test.py", testDict, testDict); 

    } 
    catch(boost::python::error_already_set& e) 
    { 
    PyErr_Print(); 
    } 
return 0; 

} 

:

import ModuleX 

Respuesta

12

Así resulta que mi problema es un simple caso de la ruta de búsqueda de módulo no se establece correctamente cuando se inicializa desde dentro de C++.

From the Python Documentation intro:

En la mayoría de los sistemas (en particular, en Unix y Windows, aunque los detalles son ligeramente diferentes), Py_Initialize() calcula la ruta de búsqueda de módulo de en base a su mejor estimación para la ubicación de el estándar ejecutable del intérprete de Python, suponiendo que la biblioteca de Python es encontrada en una ubicación fija relativa al intérprete de Python ejecutable. En particular, busca un directorio llamado lib/pythonX.Y relativo al directorio principal donde se encuentra el ejecutable denominado python en la ruta de búsqueda del comando de shell (la variable de entorno RUTA).

Lo que esto significa es que la ruta de búsqueda del módulo de ninguna manera está configurada para apuntar al directorio de trabajo actual, sino que apunta a la carpeta de instalación del sistema python.

La solución para mí fue establecer correctamente la ruta de búsqueda del módulo para apuntar al directorio de trabajo actual. Para hacer esto, necesita inicializar python y luego extraer el valor sys.path y agregar rutas adicionales. Disculpe el uso de impulso si no le gusta eso; debería poder ver fácilmente cómo sustituir cualquier cadena deseada.

Py_Initialize(); 

// now time to insert the current working directory into the python path so module search can take advantage 
// this must happen after python has been initialised 
boost::filesystem::path workingDir = boost::filesystem::absolute("./").normalize(); 
PyObject* sysPath = PySys_GetObject("path"); 
PyList_Insert(sysPath, 0, PyString_FromString(workingDir.string().c_str())); 
+0

Para Python3 reemplace 'PyString_FromString' con' PyBytes_FromString' – schuess

Cuestiones relacionadas