Implementation of garbage classification smart trash can project based on OrangePi Zero 2 (2) C language calling Python code–installation and testing of dev dependent libraries of libpython3

Environment Construction and Testing

If you want to call python code in C language, you need to install the dev dependency library of libpython3

Installation: dev dependency library of libpython3

Use the following command to check whether dependent packages already exist:

dpkg -l | grep libpython3

It can be seen that there is no library with the suffix “-dev”, so you need to execute the following instructions to install it:

sudo apt install libpython3.10-dev

After the installation is complete, check again and you will see “libpython3.10-dev“:

Test: C language executes python code

test.c

#include "Python.h" //Header file of Python API, used to access Python objects and functions
 
int main()
{
Py_Initialize(); //Initialize the Python interpreter so that Python code can be executed in the C program
PyRun_SimpleString("print('successful')"); //Execute a simple Python code
Py_Finalize(); //Close the Python interpreter and release resources
 
}

Compile statement:

gcc test.c -I /usr/include/python3.10 -l python3.10
//"-I" specifies the python header file path; "-l" specifies the python library file path

Output result:

C language executes python function

The steps are roughly as follows (use the functions and parameters in order, no tricks at all)

  1. Includes the Python.h header file to use the Python API
  2. Usevoid Py_Initialize() to initialize the Python interpreter
  3. Use PyObject *PyImport_ImportModule(const char *name) and PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name) to get the sys.path object, and use int PyList_Append(PyObject *list, PyObject *item)Add the current path to sys.path to load the current Python module (Python file is python module)
  4. Use the PyObject *PyImport_ImportModule(const char *name) function to import the Python module and check if there are any errors
  5. Use the PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name) function to get the Python function object and check whether it is callable
  6. Use the PyObject *Py_BuildValue(const char *format, …) function to convert the C-type data structure into a Python object as a parameter of the Python function. If there are no parameters, there is no need to call it.
  7. Use the PyObject *PyObject_CallObject(PyObject *callable, PyObject *args) function to call the Python function and get the return value
  8. Use the int PyArg_Parse(PyObject *args, const char *format, …) function to convert the return value to the C type and check if there is an error. If there is no return value, there is no need to call it.
  9. Release all referenced Python objects using the void Py_DECREF(PyObject *o) function
  10. At the end, call the void Py_Finalize() function to close the Python interpreter

6 and 7 are used when operating Python parameterized functions, and can be ignored for parameterless functions

1. C language calls Python function without parameters

First, write a separate python file in which a function without parameters and return value is defined:

nopara.py

def good_luck():
    print('successful');

Then write a C program to call it:

nopara.c

#include "Python.h"//Include the Python.h header file to use the Python API

int main(){
Py_Initialize();//Initialize the Python interpreter
\t
PyObject *sys=PyImport_ImportModule("sys");
PyObject *path=PyObject_GetAttrString(sys,"path");//Get the sys.path object
PyList_Append(path,PyUnicode_FromString("."));//Add the current path to sys.path to load the current Python module (Python file)
\t
PyObject *pModule=PyImport_ImportModule("nopara");//Import the Python module and check whether there are errors
if(!pModule){
PyErr_Print();
printf("Error: failed to load nopara.py\\
");
}

PyObject *pFun=PyObject_GetAttrString(pModule,"good_luck");//Get the Python function object and check whether it is callable
 if(!pFun){
                PyErr_Print();
                printf("Error: failed to load good_luck\\
");
        }
\t
PyObject *pValue=PyObject_CallObject(pFun,NULL);//Call the Python function and get the return value
if(!pValue){
                PyErr_Print();
                printf("Error: failed to load pFun\\
");
        }

Py_DECREF(pValue);//Release all referenced Python objects
        Py_DECREF(pFun);
Py_DECREF(pModule);

Py_Finalize();//Close the Python interpreter

return 0;
}

Compile statement:

gcc nopara.c -I /usr/include/python3.10 -l python3.10
//"-I" specifies the python header file path; "-l" specifies the python library file path

Output results:

2. C language calls Python functions with parameters

First, write a separate python file in which a function with parameters and return value is defined:

para.py

def good_luck(s):
    print(s)
    return s

Then write a C program to call it:

para.c

#include "Python.h"//Include the Python.h header file to use the Python API

int main(){
Py_Initialize();//Initialize the Python interpreter
\t
PyObject *sys=PyImport_ImportModule("sys");
PyObject *path=PyObject_GetAttrString(sys,"path");//Get the sys.path object
PyList_Append(path,PyUnicode_FromString("."));//Add the current path to sys.path to load the current Python module (Python file)
\t
PyObject *pModule=PyImport_ImportModule("para");//Import the Python module and check whether there are errors
if(!pModule){
PyErr_Print();
printf("Error: failed to load para.py\\
");
}



PyObject *pFun=PyObject_GetAttrString(pModule,"good_luck");//Get the Python function object and check whether it is callable
 if(!pFun){
                PyErr_Print();
                printf("Error: failed to load good_luck\\
");
        }
\t
char *category="comedy";
PyObject *pArgs=Py_BuildValue("(s)",category);//Create a Python tuple as a parameter of the Python function

PyObject *pValue=PyObject_CallObject(pFun,pArgs);//Call the Python function and get the return value
if(!pValue){
                PyErr_Print();
                printf("Error: failed to load pFun\\
");
        }

char *result=NULL;//Use a pointer to receive the return value
if(!PyArg_Parse(pValue,"s", & amp;result)){
PyErr_Print();
       printf("Error:parse failed\\
");

}

printf("result=%s\\
",result);

Py_DECREF(pValue);//Release all referenced Python objects
        Py_DECREF(pFun);
Py_DECREF(pModule);

Py_Finalize();//Close the Python interpreter

return 0;
}

Compile statement:

gcc para.c -I /usr/include/python3.10 -l python3.10
//"-I" specifies the python header file path; "-l" specifies the python library file path

Output results: