首页 > 编程语言 >如何利用c调用python代码

如何利用c调用python代码

时间:2024-04-04 19:12:43浏览次数:21  
标签:调用 const 函数 python 代码 Py Python char PyObject

C语言调用python

通过C语言调用Python代码,需要先安装libpython3的 dev依赖库(不同的ubuntu版本下,python版本 可能会有差异, 比如ubuntu 22.04里是libpython3.10-dev)。 首先可以通过以下命令验证是否是否已经存在python3的dev包

dpkg -l | grep libpython3

正常会有类似如下的输出,出现"libpython3"和 "dev",如libpython3.10-dev即可

如果没有, 可以通过apt命令安装相关的dev包:

sudo apt install libpython3.10-dev

调用无参python函数

#nopara.py文件
def say_funny():
 	print('funny')

用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 *PyObject_CallObject(PyObject *callable, PyObject *args)函数调用 Python函数,并获取返回值。
  7. 使用void Py_DECREF(PyObject *o)函数释放所有引用的Python对象。
  8. 结束时调用void Py_Finalize()函数关闭Python解释器。 相关的函数参数说明参考网站(网站左上角输入函数名即可开始搜索)。
示例代码
#include<Python.h>

int main(int argc, char const *argv[])
{
    Py_Initialize();

    PyObject *sys = PyImport_ImportModule("sys");
    PyObject *path = PyObject_GetAttrString(sys,"path");
    PyList_Append(path,PyUnicode_FromString("."));

    PyObject *pModule = PyImport_ImportModule("nopara");
    if(!pModule){
        PyErr_Print();
        printf("ERROR:failed to load nopara.py\n");
    }   

    PyObject *pFunc = PyObject_GetAttrString(pModule,"say_funny");
    if(!pFunc || !PyCallable_Check(pFunc))
    {
        PyErr_Print();
        printf("ERROR:function say_funny not found or not callable\n");
        return 1;
    }

    PyObject *pValue = PyObject_CallObject(pFunc,NULL);
    if(!pValue)
    {
        PyErr_Print();
        printf("ERROR: function call failed\n");
        return 1;
    }

    Py_DECREF(pValue);
    Py_DECREF(pFunc);
    Py_DECREF(pModule);
    Py_Finalize(); 
    return 0;
}

调用有参python函数

定义一个带参数和返回值的函数

#para.py
def say_funny(category):
    print(category)
    return category

用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, ... x )函数将C类型的数据结构转换成 Python对象,作为Python函数的参数,没有参数不需要调用

    这里要注意的是,Py_BuildValue的第一个参数是类型转换:C对应的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解释器。 相关的函数参数说明参考网站(网站左上角输入函数名即可开始搜索)。

    示例代码
#include<Python.h>

int main(int argc, char const *argv[])
{
    Py_Initialize();
	
    // 将当前路径添加到sys.path中
    PyObject *sys = PyImport_ImportModule("sys");
    PyObject *path = PyObject_GetAttrString(sys,"path");
    PyList_Append(path,PyUnicode_FromString("."));
	
    // 导入para模块
    PyObject *pModule = PyImport_ImportModule("para");
    if(!pModule){
        PyErr_Print();
        printf("ERROR:failed to load para.py\n");
    }
    
	//获取say_funny函数对象
    PyObject *pFunc = PyObject_GetAttrString(pModule,"say_funny");
    if(!pFunc || !PyCallable_Check(pFunc))
    {
        PyErr_Print();
        printf("ERROR:function say_funny not found or not callable\n");
        return 1;
    }
    
	//创建一个字符串作为参数
    char *category = "comedy";
    PyObject *pArgs = Py_BuildValue("(s)",category);

    //调用say_funny函数并获取返回值
    PyObject *pValue = PyObject_CallObject(pFunc,pArgs);
    if(!pValue)
    {
        PyErr_Print();
        printf("ERROR: function call failed\n");
        return 1;
    }
	
    //将返回值转换为C类型
    char *result = NULL;
    if(!PyArg_Parse(pValue,"s",&result))
    {
        PyErr_Print();
        printf("Error: parse failed\n");
    }
    
	//打印返回值
    printf("pValue=%s\n",result);

    //释放所有引用的Python对象
    Py_DECREF(pValue);
    Py_DECREF(pFunc);
    Py_DECREF(pModule);
    //释放所有引用的Python对象
    Py_Finalize(); 
    return 0;
}

标签:调用,const,函数,python,代码,Py,Python,char,PyObject
From: https://www.cnblogs.com/keep--fighting/p/18114495

相关文章

  • 基于深度学习的安全帽检测系统(网页版+YOLOv8/v7/v6/v5代码+训练数据集)
    摘要:本文深入研究了基于YOLOv8/v7/v6/v5的安全帽检测,核心采用YOLOv8并整合了YOLOv7、YOLOv6、YOLOv5算法,进行性能指标对比。详述了国内外研究现状、数据集处理、算法原理、模型构建与训练代码,及基于Streamlit的交互式Web应用界面设计。在Web网页中可以支持图像、视频和实时摄像头......
  • DFS 全排列问题 C语言代码
    深度优先搜索(DFS)是一种遍历算法,尽可能深地向子树中的结点搜索,直到达到一定的深度,再回溯到上层的结点,继续搜索未被访问的结点。全排列问题给定4个数1234,求他们所有可能的排列结果。代码#include<stdio.h>voiddfs(intx);inti;inta[4];intresult[4];/......
  • Python数据分析与可视化笔记 九 分类问题
    分类        分类是找出数据库中一组数据对象的共同特点,并按照分类模式将其划分为不同的类,其目的是通过分类模型,将数据库中的数据项映射到某个给定的类别。        分类学习是一类监督学习的问题,训练数据会包含其分类结果,根据分类结果分为以下几种问题。1.......
  • 11.python的字典dict(下) 遍历字典,结构优化
    11.python的字典dict(下)遍历所有的键值对items()方法是字典的一个内置方法,用于返回字典中所有键值对的视图(view)。它返回一个可迭代的对象,每个元素都是一个包含键和对应值的元组。下面用一个例子来说明items()方法的用法:dict1={'name':'John','age':25,'job':'En......
  • Python企业面试题1 —— 基础篇
    1.b、B、KB、MB、GB的关系?b----位(bit)B----字节(一个字节等于8位)1B=8bit1KB=1024B1MB=1024KB1GB=1024MB2.PE8规范1.使用4个空格而不是tab键进行缩进。2.每行长度不能超过79。3.使用空行来间隔函数和类。4.必要时候,在每一行下写注释。5.......
  • python相对路径导包与绝对路径导包的正确方式
    【python相对路径导包与绝对路径导包的正确方式】python相对路径导包与绝对路径导包的正确方式_哔哩哔哩_bilibilipython导包的难题,今天解决了,相对路径导包和绝对路径导包,均可以!!!,视频播放量5、弹幕量0、点赞数0、投硬币枚数0、收藏人数0、转发人数1,视频作者天龙战神......
  • 基于深度学习的景区垃圾识别系统(网页版+YOLOv8/v7/v6/v5代码+训练数据集)
    摘要:本文深入研究了基于YOLOv8/v7/v6/v5的景区垃圾识别系统,核心采用YOLOv8并整合了YOLOv7、YOLOv6、YOLOv5算法,进行性能指标对比;详述了国内外研究现状、数据集处理、算法原理、模型构建与训练代码,及基于Streamlit的交互式Web应用界面设计。在Web网页中可以支持图像、视频和实时摄......
  • 利用AI结合无极低码(免费版)快速实现接口开发教程,会sql即可,不需要编写编译代码
    无极低码无代码写服务+AI实践本次演示最简单的单表无代码增删改查发布服务功能,更复杂的多表操作,安全验证,多接口调用,自自动生成接口服务,生成二开代码,生成调用接口测试,一键生成管理界面多条件检索、修改、删除、查看、通用公共接口调用、通用无限级字典调用等后续逐步更新,请......
  • Python+requests+Pytest+logging+allure+pymysql框架详解
    一、框架目录结构1)tools目录用来放公共方法存储,如发送接口以及读取测试数据的方法,响应断言数据库断言前置sql等方法;2)datas目录用例存储接口用例的测试数据,我是用excel来存储的数据,文件数据图片数据等;3)testcases目录用来存放测试用例,一个python文件对应一个接口模块的......
  • Python从0到100(十):Python集合介绍及运用
    一、集合定义定义:由不同元素组成的集合,集合是一组无序排列可hash值,可作为字典的key。特性:集合的目的是将不同的值存放在一起,不同的集合间用来做关系运算,无须纠结于集合中的单个值。(1、不同元素组成2、无序3、集合中的元素必须是不可变类型)二、创建集合在Python中......