基于OrangePi Zero 2实现垃圾分类智能垃圾桶项目(2)C语言调用Python代码--libpython3的dev依赖库的安装与测试

 环境搭建与测试

如果想要在C语言中调用python的代码,需要安装libpython3的dev依赖库

安装:libpython3的dev依赖库

通过以下命令查看是否已经存在依赖包:

dpkg -l | grep libpython3

可见并不存在后缀为“-dev” 的库,因此需要执行以下指令安装:

sudo apt install libpython3.10-dev

  安装完成后再次查看就可以看到“libpython3.10-dev”了:

测试 :C语言执行python代码

test.c

#include "Python.h" //Python API的头文件,用于访问Python对象和函数
 
int main()
{
	Py_Initialize(); //初始化Python解释器,这样可以在C程序中执行Python代码
	PyRun_SimpleString("print('successful')"); //执行一段简单的Python代码
	Py_Finalize(); //关闭Python解释器,并释放资源
 
}

编译语句:

gcc test.c -I /usr/include/python3.10 -l python3.10
//“-I”指定python头文件路径;“-l”指定python库文件路径

 输出结果:

C语言执行python函数

步骤大体如下(按顺序用对函数和参数,无技巧可言)

  1.     包含Python.h头文件,以便使用Python API
  2.     使用void Py_Initialize()初始化Python解释器
  3.     使用 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模块)
  4.     使用PyObject *PyImport_ImportModule(const char *name)函数导入Python模块,并检查是否有错误
  5.     使用PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)函数获取 Python函数对象,并检查是否可调用
  6.     使用PyObject *Py_BuildValue(const char *format, ...)函数将C类型的数据结构转换成Python对 象,作为Python函数的参数, 没有参数则不需要调用
  7.     使用PyObject *PyObject_CallObject(PyObject *callable, PyObject *args)函数调用Python 函数,并获取返回值
  8.     使用int PyArg_Parse(PyObject *args, const char *format, ...)函数将返回值转换为C类型, 并检查是否有错误, 没有返回值时则不需要调用
  9.     使用void Py_DECREF(PyObject *o)函数释放所有引用的Python对象
  10.     结束时调用void Py_Finalize()函数关闭Python解释器

 6和7是操作Python有参函数时用的,对于无参函数可忽略

1、C语言调用无参Python函数

首先,单独写一个python文件,其中定义一个不带参数和返回值的函数:

nopara.py

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

然后在写一个C程序来调用它: 

nopara.c

#include "Python.h"//包含Python.h头文件,以便使用Python API

int main(){
	Py_Initialize();//初始化Python解释器
	
	PyObject *sys=PyImport_ImportModule("sys");
	PyObject *path=PyObject_GetAttrString(sys,"path");//获取sys.path对象
	PyList_Append(path,PyUnicode_FromString("."));//将当前路径添加到sys.path中,以便加载当前Pythn模块(Python文件)
	
	PyObject *pModule=PyImport_ImportModule("nopara");//导入Python模块,并检查是否有误
	if(!pModule){
		PyErr_Print();
		printf("Error:failed to load nopara.py\n");
	}

	PyObject *pFun=PyObject_GetAttrString(pModule,"good_luck");//获取Python函数对象,并检查是否可调用
 	if(!pFun){
                PyErr_Print();
                printf("Error:failed to load good_luck\n");
        }
	
	PyObject *pValue=PyObject_CallObject(pFun,NULL);//调用Python函数,并获取返回值
	 if(!pValue){
                PyErr_Print();
                printf("Error:failed to load pFun\n");
        }

	Py_DECREF(pValue);//释放所有引用的Python对象
        Py_DECREF(pFun);
	Py_DECREF(pModule);	

	Py_Finalize();//关闭Python解释器

	return 0;
}

 编译语句:

gcc nopara.c -I /usr/include/python3.10 -l python3.10
//“-I”指定python头文件路径;“-l”指定python库文件路径

输出结果:

2、C语言调用有参Python函数

首先,单独写一个python文件,其中定义一个带参数和返回值的函数:

para.py

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

然后在写一个C程序来调用它:

para.c

#include "Python.h"//包含Python.h头文件,以便使用Python API

int main(){
	Py_Initialize();//初始化Python解释器
	
	PyObject *sys=PyImport_ImportModule("sys");
	PyObject *path=PyObject_GetAttrString(sys,"path");//获取sys.path对象
	PyList_Append(path,PyUnicode_FromString("."));//将当前路径添加到sys.path中,以便加载当前Pythn模块(Python文件)
	
	PyObject *pModule=PyImport_ImportModule("para");//导入Python模块,并检查是否有误
	if(!pModule){
		PyErr_Print();
		printf("Error:failed to load para.py\n");
	}



	PyObject *pFun=PyObject_GetAttrString(pModule,"good_luck");//获取Python函数对象,并检查是否可调用
 	if(!pFun){
                PyErr_Print();
                printf("Error:failed to load good_luck\n");
        }
	
	char *category="comedy";
	PyObject *pArgs=Py_BuildValue("(s)",category);//创建一个Python元组,作为Python函数的参数

	PyObject *pValue=PyObject_CallObject(pFun,pArgs);//调用Python函数,并获取返回值
	 if(!pValue){
                PyErr_Print();
                printf("Error:failed to load pFun\n");
        }

	char *result=NULL;//用指针来接收返回值
	if(!PyArg_Parse(pValue,"s",&result)){
		 PyErr_Print();
       		 printf("Error:parse failed\n");

	}

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

	Py_DECREF(pValue);//释放所有引用的Python对象
        Py_DECREF(pFun);
	Py_DECREF(pModule);	

	Py_Finalize();//关闭Python解释器

	return 0;
}

 编译语句:

gcc para.c -I /usr/include/python3.10 -l python3.10
//“-I”指定python头文件路径;“-l”指定python库文件路径

输出结果:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值