Python Embedding en C ++: ImportError: No hay un módulo llamado pyfunction

Hola, estoy tratando de incrustar python (2.7) en C ++ (g ++ 4.8.2) y por lo tanto llamar a una función python desde C ++. Este es el código básico que se proporciona en la documentación de Python para incrustar:

Este es mi archivo call_function.cpp

#include  int main(int argc, char *argv[]) { PyObject *pName, *pModule, *pDict, *pFunc; PyObject *pArgs, *pValue; int i; if (argc < 3) { fprintf(stderr,"Usage: call pythonfile funcname [args]\n"); return 1; } /* char pySearchPath[] = "/usr/include/python2.7"; Py_SetPythonHome(pySearchPath);*/ Py_Initialize(); pName = PyString_FromString(argv[1]); /* Error checking of pName left out */ pModule = PyImport_Import(pName); Py_DECREF(pName); if (pModule != NULL) { pFunc = PyObject_GetAttrString(pModule, argv[2]); /* pFunc is a new reference */ if (pFunc && PyCallable_Check(pFunc)) { pArgs = PyTuple_New(argc - 3); for (i = 0; i < argc - 3; ++i) { pValue = PyInt_FromLong(atoi(argv[i + 3])); if (!pValue) { Py_DECREF(pArgs); Py_DECREF(pModule); fprintf(stderr, "Cannot convert argument\n"); return 1; } /* pValue reference stolen here: */ PyTuple_SetItem(pArgs, i, pValue); } pValue = PyObject_CallObject(pFunc, pArgs); Py_DECREF(pArgs); if (pValue != NULL) { printf("Result of call: %ld\n", PyInt_AsLong(pValue)); Py_DECREF(pValue); } else { Py_DECREF(pFunc); Py_DECREF(pModule); PyErr_Print(); fprintf(stderr,"Call failed\n"); return 1; } } else { if (PyErr_Occurred()) PyErr_Print(); fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]); } Py_XDECREF(pFunc); Py_DECREF(pModule); } else { PyErr_Print(); fprintf(stderr, "Failed to load \"%s\"\n", argv[1]); return 1; } Py_Finalize(); return 0; } 

Ahora mi script de python se guarda como pyfunction.py colocado en la misma carpeta que call_function.cpp.

Esto es pyfunction.py:

 def multiply(a,b): print "Will compute", a, "times", b c = 0 for i in range(0, a): c = c + b return c 

Ahora usando la Terminal que estoy llamando:

 $ g++ call_function.cpp -I/usr/include/python2.7 -lpython2.7 -o call_function 

(Comstack exitosamente sin ningún error) (Ejecutando el progtwig)

 $ ./call_function pyfunction multiply 2 3 

(Me sale este ERROR):

 ImportError: No module named pyfunction Failed to load "pyfunction" 

No entiendo cómo esto es posible. He seguido la documentación y todavía estoy recibiendo el error.

¿Cómo no puede encontrar pyfunction.py cuando se coloca en el mismo directorio.

Prueba este:

  $ PYTHONPATH=. ./call_function pyfunction multiply 2 3 

si esto no funciona, intente crear el archivo __init__.py en este directorio e intente nuevamente.

ACTUALIZAR:

Creo que PYTHONPATH es una solución temporal, para probar cosas. Si desea tener un directorio cuando todos sus módulos integrados estén en funcionamiento, debe poner en su intérprete integrado algo que se ajuste a esto:

 import sys sys.path.insert(0, "./path/to/your/modules/") 

Probablemente puede hacerlo en python en su intérprete o en el nivel C. Esto agregará la ruta de búsqueda de manera muy similar a PYTHONPATH pero es más persistente y elegante (IMHO).

Coloque lo siguiente en el código C / C ++, justo después de Py_Initialize();

 PyRun_SimpleString("import sys"); PyRun_SimpleString("sys.path.append(\".\")"); 

Hola a todos aquellos que enfrentan el mismo problema, encontré la solución! setenv () es una función definida en stdlib.h que establece la variable de entorno. Solo hay que correrlo!

 setenv("PYTHONPATH",".",1); 

Para más información sobre setenv:

 $ man setenv 

Todo lo mejor 🙂 Además, gracias a @spinus

La solución provista por Spinus funciona si el archivo python no importa ninguna biblioteca python adicional.

Sin embargo, si un archivo python importa una biblioteca adicional, digamos numpy, el código anterior se bloquea de la siguiente manera:

 :~/programs/python$ ./a.out myModule multiply 4 3 Traceback (most recent call last): File "/home/a/programs/python/myModule.py", line 1, in  import numpy ImportError: No module named 'numpy' Failed to load "myModule" 

Como observación, la importación de la biblioteca python desde C no funciona:

 PyObject *pNumpy = PyUnicode_FromString("numpy"); PyObject *pModuleA = PyImport_Import(pNumpy); 

¿Alguien sabe cómo llamar desde C python-functions, que dependen de otras bibliotecas de python?