问题
I have an application in C and at some point I need to solve a non-linear optimization problem. Unfortunately AFAIK there are very limited resources to do that in C (please let me know otherwise). However it is quite simple to do it in Python, e.g. scipy.optimize.minimize.
While I was trying to do that I encountered some of what it seems to be very frequent pitfalls, e.g. Python.h
not found, module not loading, segmentation fault on function call, etc.
What is a quick and easy first-timer’s way to link the two programs?
回答1:
There are some things that you have to make sure are in place in order to make this work:
- Make sure you have Python installed (you may need the
python-dev
package). - Locate your
Python.h
file, e.g. bylocate Python.h
. One of the occurrences should be in a sub(sub)folder in theinclude
folder, e.g. the path should be something like../include/python2.7/Python.h
. - Insert
#include “<path_to_Python.h>"
in your C code in order to be able to use the Python API. Use any tutorial to call your Python function. I used this one and it did the trick. However there were a couple of small points missing:
Whenever you use any
Py<Name>
function, e.g.PyImport_Import()
, always check the result to make sure there was no error, e.g.// Load the module object pModule = PyImport_Import(pName); if (!pModule) { PyErr_Print(); printf("ERROR in pModule\n"); exit(1); }
Immediately after initializing the Python interpreter, i.e. after
Py_Initialize();
, you have to append the current path tosys.path
in order to be able to load your module (assuming it is located in your current directory):PyObject *sys = PyImport_ImportModule("sys"); PyObject *path = PyObject_GetAttrString(sys, "path"); PyList_Append(path, PyString_FromString("."));
- Keep in mind that when you give the name of your Python file, it has to be without the extension
.py
. - Lastly, you have to do the following during compiling/linking:
- Remember the
../include/python2.7/Python.h
file you used before? Include theinclude
folder in the list of the header files directories with the-I
option in thegcc
options during compilation, e.g.-I /System/Library/Frameworks/Python.framework/Versions/2.7/include
. - Also pass to the linker the folder with the required libraries. It should be inside the same folder where the
include
folder is located, e.g.-L /System/Library/Frameworks/Python.framework/Versions/2.7/lib
, along with the-lpython2.7
option (of course adjusting it accordingly to your Python version).
- Remember the
Now you must be able to successfully compile and execute your C program that calls in it your Python program.
I hope this was helpful and good luck!
Sources:
- How do you call Python code from C code?
- http://www.linuxjournal.com/article/8497?page=0,1
- http://www.codeproject.com/Articles/11805/Embedding-Python-in-C-C-Part-I
- http://www.codeproject.com/Articles/11843/Embedding-Python-in-C-C-Part-II
- Python C API doesn't load module
- What sets up sys.path with Python, and when?
- http://linux.die.net/man/1/gcc
- PyObject segfault on function call
- I have Python on my Ubuntu system, but gcc can't find Python.h
- How do you call Python code from C code?
来源:https://stackoverflow.com/questions/25316485/call-a-python-function-from-within-a-c-program