I am trying to embed a python program inside a C program. My OS is Ubuntu 14.04
I try to embed python 2.7 and python 3.4 interpreter in the same C code base (as separate applications). The compilation and linking works when embedding python 2.7 but not for the python 3.4. It fails during the linker stage.
Here is my C code (just an example not real code)
simple.c
#include <stdio.h>
#include <Python.h>int main(int argc, char *argv[])
{PyObject *pName, *pModule, *pFunc, *pValue;char module[] = "get_version";char func[] = "get_version";char module_path[] = ".";Py_Initialize();PyObject *sys_path = PySys_GetObject("path");PyList_Append(sys_path, PyUnicode_FromString(module_path));pName = PyUnicode_FromString(module);pModule = PyImport_Import(pName);Py_DECREF(pName);if(pModule != NULL){pFunc = PyObject_GetAttrString(pModule, func);if (pFunc && PyCallable_Check(pFunc)){pValue = PyObject_CallObject(pFunc, NULL);if (pValue != NULL) {printf("Python version: %s\n", PyString_AsString(pValue));Py_DECREF(pValue);}else {Py_DECREF(pFunc);Py_DECREF(pModule);PyErr_Print();fprintf(stderr,"Call failed\n");return 1;}}}Py_Finalize();return 0;
}
get_version.py
import sysdef get_version():version = '.'.join(str(v) for v in sys.version_info[:3])print("version: ", version)return version
I compile the program using gcc. First with compiling and linking flags set to python 2.7 I run the compilation and linking by using following command:
gcc `python-config --cflags` simple.c `python-config --ldflags`
The flags expand as:
python-config --cflags: -I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7 -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes
python-config --ldflags: -L/usr/lib/python2.7/config-x86_64-linux-gnu -L/usr/lib -lpthread -ldl -lutil -lm -lpython2.7 -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions
It works fine without any issues. When I try to compile the same with python3.4 flags it fails:
gcc `python3-config --cflags` simple.c `python3-config --ldflags`
The flags expand as:
python-config --cflags: -I/usr/include/python3.4m -I/usr/include/python3.4m -Wno-unused-result -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes
python-config --ldflags: -L/usr/lib/python3.4/config-3.4m-x86_64-linux-gnu -L/usr/lib -lpython3.4m -lpthread -ldl -lutil -lm -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions
Error message:
simple.c: In function ‘main’:
simple.c:27:17: warning: implicit declaration of function ‘PyString_AsString’ [-Wimplicit-function-declaration]printf("Python version: %s\n", PyString_AsString(pValue));^
simple.c:27:17: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
/tmp/ccaoMdTo.o: In function `main':
/home/vagrant/c_python_api/simple.c:27: undefined reference to `PyString_AsString'
collect2: error: ld returned 1 exit status
I tried by changing the order in which linker objects are specified. But no luck. Any idea why this would be the case?
Thanks for the help!!