C语言调用Python

本文详细介绍了如何在C语言中通过PythonAPI调用无参和有参的Python函数,涉及头文件引用、sys.path的使用以及Python对象的导入、调用和资源管理。
摘要由CSDN通过智能技术生成

目录

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、调用无参函数

  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 *PyObject_CallObject(PyObject *callable, PyObject *args)函数调用 Python函数,并获取返回值。
  7. 使用void Py_DECREF(PyObject *o)函数释放所有引用的Python对象。
  8. 结束时调用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、调用有参函数 

其实调用有参函数与无参函数的区别只在我们有没有传参,如果有返回值我们就需要获取返回值

  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解释器。

第三步也可以自行更改

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 

运行结果 

  • 49
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言是一种高级编程语言,而Python也是一种高级编程语言。在C语言调用Python程序可以通过使用Python的解释器来实现。要在C语言调用Python程序,首先需要在C中包含Python的头文件,以便可以使用Python的函数和数据结构。 在C代码中,可以使用Py_Initialize()函数来初始化Python解释器。然后可以使用PyRun_SimpleString()函数或PyRun_SimpleFile()函数来执行Python代码。这样可以将C语言中的数据传递给Python程序进行处理,并获取Python的返回结果。 此外,还可以使用PyImport_ImportModule()函数来导入Python模块,并使用PyObject_CallObject()函数来调用Python函数。通过这些函数的使用,可以在C语言中直接调用Python函数。 在调用Python程序之前,需要先确保Python解释器已经安装在计算机上,并且路径已正确配置好。可以通过设置环境变量或在代码中指定Python解释器的路径来实现。 需要注意的是,在调用Python程序时,C语言Python存储数据的方式是不同的。所以在C语言Python之间传递数据时,需要进行数据类型的转换。可以使用PyArg_ParseTuple()函数来将C语言的数据类型转换为Python的数据类型,或使用Py_BuildValue()函数将Python的数据类型转换为C语言的数据类型。 总之,通过上述方法,我们可以在C语言调用Python程序,实现C语言Python的互操作。这样可以充分利用C语言的性能和Python的灵活性,来开发更加复杂和强大的应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值