Hi I'm trying to embed python (2.7) into C++ (g++ 4.8.2) and hence call a python function from C++. This is the basic code provided in python documentation for embedding:
This is my file call_function.cpp
#include <Python.h>
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;
}
Now my python script is saved as pyfunction.py placed in the same folder as call_function.cpp.
This is 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
Now using the Terminal I'm calling :
$ g++ call_function.cpp -I/usr/include/python2.7 -lpython2.7 -o call_function
(Compiles successfully without any errors) (Running the program)
$ ./call_function pyfunction multiply 2 3
(I get this ERROR):
ImportError: No module named pyfunction
Failed to load "pyfunction"
I don't understand how this is possible. I've followed the documentation and still I'm getting the error.
How can it not find pyfunction.py when it is placed in the same directory.
Put the following in the C/C++ code, just after Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\".\")");
Try this one:
$ PYTHONPATH=. ./call_function pyfunction multiply 2 3
if this won't work, try to make __init__.py
file in this directory and try again.
UPDATE:
I think that PYTHONPATH
is temporary solution, to test stuff.
If you want to have a directory when all your embedded modules lives you have to put in your embedded interpreter something equilevant to this:
import sys
sys.path.insert(0, "./path/to/your/modules/")
You can do it probably in python in your interpreter or on C level.
This will add search path in very similar manner as PYTHONPATH
but it is more persistant and elegant (IMHO).
Hi to all those facing the same problem, I found the solution! setenv() is a function defined in stdlib.h which sets the environment variable. Just have to run it!
setenv("PYTHONPATH",".",1);
for more info on setenv:
$ man setenv
All the best :) Also, thanks to @spinus
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With