Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
501 views
in Technique[技术] by (71.8m points)

c++ - Call a Python function from within a C program

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

There are some things that you have to make sure are in place in order to make this work:

  1. Make sure you have Python installed (you may need the python-dev package).
  2. Locate your Python.h file, e.g. by locate Python.h. One of the occurrences should be in a sub(sub)folder in the include folder, e.g. the path should be something like ../include/python2.7/Python.h.
  3. Insert #include “<path_to_Python.h>" in your C code in order to be able to use the Python API.
  4. 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
      ");
          exit(1);
      }
      
    • Immediately after initializing the Python interpreter, i.e. after Py_Initialize();, you have to append the current path to sys.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("."));
      
  5. Keep in mind that when you give the name of your Python file, it has to be without the extension .py.
  6. Lastly, you have to do the following during compiling/linking:
    • Remember the ../include/python2.7/Python.h file you used before? Include the include folder in the list of the header files directories with the -I option in the gcc 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).

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:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...