目录
1.直接调用python语句
头文件引用
2.调用无参有参函数
1、调用无参函数
1.建立nopara.py文件
2.使用c语言根据上面流程进行调用
2、调用有参函数
1.建立nopara.py文件
2.使用c语言根据上面流程进行调用
C语言调用python需要我们已经安装好了libpython3的 dev依赖库,如果还没安装的可以看我之前的文档搭建python编译环境-CSDN博客
1.直接调用python语句
- 头文件Python.h,这是Python API的头文件,用于访问Python对象和函数
- Py_Initialize();函数初始化Python解释器
- PyRun_SimpleString();函数可以执行一段简单的Python代码,例如打印"funny"。需要传递一个字 符串作为参数,表示要执行的Python代码,如print ('funny')这么一个Python代码字符串。
- Py_Finalize()函数关闭Python解释器,并释放资源。
#include "Python.h"
int main()
{
Py_Initialize(); // 初始化
PyRun_SimpleString("print ('happy')");
Py_Finalize(); //释放资源
}
运行这个程序我们要使用以下命令进行编译(我的python版本是Python 3.10)
gcc simpledemo.c -o simpledemo -I /usr/include/python3.10 -lpython3.10//编译
./simpledemo//运行
头文件引用
/usr/include
:Linux系统编程往往需要引用c头文件,linux下,头文件一般存储到/usr/include
若头文件在此文件夹内,相对路径直接引入即可
#include<stdio.h>
#include<netient/ip.h>
若在其他文件夹,gcc编译需要声明-I指定路径
gcc -I /usr/xxx/include yyy.c
运行结果
2.调用无参有参函数
关于sys.path的用法及介绍可以看这篇博文
sys.path用法介绍-CSDN博客
1、调用无参函数
- 包含Python.h头文件,以便使用Python API。
- 使用void Py_Initialize()初始化Python解释器,
- 使用PyObject *PyImport_ImportModule(const char *name)和PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)获取sys.path对象,并利用 int PyList_Append(PyObject *list, PyObject *item)将当前路径.添加到sys.path中,以便加载当前的Python模块(Python文件即python模块)。
- 使用PyObject *PyImport_ImportModule(const char *name)函数导入Python模块,并检查是否有错误。
- 使用PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)函数获取 Python函数对象,并检查是否可调用。
- 使用PyObject *PyObject_CallObject(PyObject *callable, PyObject *args)函数调用 Python函数,并获取返回值。
- 使用void Py_DECREF(PyObject *o)函数释放所有引用的Python对象。
- 结束时调用void Py_Finalize()函数关闭Python解释器。
第三步可以改成这两句获取sys.path对象和添加当前路径到sys.path中
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
1.建立nopara.py文件
#nopara.py文件
def say_funny():
print('funny')
2.使用c语言根据上面流程进行调用
#include <Python.h>
int main(){
Py_Initialize();//初始化python解释器,他会加载我们python的编译环境
PyObject *pyob = PyImport_ImportModule("sys");//获取sys模块
PyObject *list = PyObject_GetAttrString(pyob,"path");//获取sys.path对象
PyList_Append(list,PyUnicode_FromString("."));//将当前路径添加到sys.path中
PyObject *mode = PyImport_ImportModule("nopara");//导入python模块,就是导入要执行的python文件
if(!mode){
PyErr_Print();
printf("ERROR:mode not!\n");
}
PyObject *pFunc = PyObject_GetAttrString(mode,"say_funny");
if(!pFunc|| !PyCallable_Check(pFunc)){
PyErr_Print();
printf("ERROR:pFunc not!\n");
}
PyObject *pValue = PyObject_CallObject(pFunc,NULL);
if(!pValue){
PyErr_Print();
printf("ERROR:pValue not!\n");
}
Py_DECREF(pValue);
Py_DECREF(pFunc);
Py_DECREF(mode);
Py_Finalize();
return 0;
}
2、调用有参函数
其实调用有参函数与无参函数的区别只在我们有没有传参,如果有返回值我们就需要获取返回值
- 包含Python.h头文件,以便使用Python API。
- 使用void Py_Initialize()初始化Python解释器,
- 使用PyObject *PyImport_ImportModule(const char *name)和PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)获取sys.path对象,并利用 int PyList_Append(PyObject *list, PyObject *item)将当前路径.添加到sys.path中,以便加载 当前的Python模块(Python文件即python模块)。
- 使用PyObject *PyImport_ImportModule(const char *name)函数导入Python模块,并检查是否有错误。
- 使用PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)函数获取 Python函数对象,并检查是否可调用。
- 使用PyObject *Py_BuildValue(const char *format, ...)函数将C类型的数据结构转换成 Python对象,作为Python函数的参数,没有参数不需要调用
- 使用PyObject *PyObject_CallObject(PyObject *callable, PyObject *args)函数调用 Python函数,并获取返回值。
- 使用int PyArg_Parse(PyObject *args, const char *format, ...)函数将返回值转换为C类 型,并检查是否有错误,没有返回值时不需要调用。
- 使用void Py_DECREF(PyObject *o)函数释放所有引用的Python对象。
- 结束时调用void Py_Finalize()函数关闭Python解释器。
第三步也可以自行更改
1.建立nopara.py文件
#nopara.py文件
def say_funny(category):
print(category)
return category
2.使用c语言根据上面流程进行调用
int main(){
Py_Initialize();//初始化python解释器,他会加载我们python的编译环境
// PyObject *pyob = PyImport_ImportModule("sys");//获取sys模块
// PyObject *list = PyObject_GetAttrString(pyob,"path");//获取sys.path对象
// PyList_Append(list,PyUnicode_FromString("."));//将当前路径添加到sys.path中
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./')");
PyObject *mode = PyImport_ImportModule("nopara");//导入python模块,就是导入要执行的python文件
if(!mode){
PyErr_Print();
printf("ERROR:mode not!\n");
}
//获取python函数对象,并检查是否可被调用
PyObject *pFunc = PyObject_GetAttrString(mode,"say_funny");
if(!pFunc|| !PyCallable_Check(pFunc)){
PyErr_Print();
printf("ERROR:pFunc not!\n");
}
char *p = "happy day!!!";
PyObject* pArgs = Py_BuildValue("(s)",p);
//调用python函数,并获取其返回值,就是执行那个函数
PyObject *pValue = PyObject_CallObject(pFunc,pArgs);
if(!pValue){
PyErr_Print();
printf("ERROR:pValue not!\n");
}
char *result = NULL;
if (!PyArg_Parse(pValue, "s", &result))
{
PyErr_Print();
printf("Error: parse failed\n");
}
printf("c=%s\n",result);
//释放所有引用的python对象
Py_DECREF(pValue);
Py_DECREF(pFunc);
Py_DECREF(mode);
//关闭python解释器
Py_Finalize();
return 0;
}
使用以下代码进行编译运行
gcc -o pymode02_2 pymode02.c -I /usr/include/python3.10/ -lpython3.10
sudo ./pymode02_2
运行结果