c调用python , 有参无参

news2024/11/17 15:30:29

文章目录

  • 1. c语言调用python 的步骤
    • 1.1 包含头文件
    • 1.2 初始化Python解释器
    • 1.3 添加当前路径到sys.path 中
    • 1.4 导入要调用的模块
    • 1.5 获取函数对象
      • 1.5.1 检查函数对象是否可被调用
    • 1.6 构造参数
    • 1.7 调用函数并获取返回值
    • 1.8 返回值解析
    • 1.9 释放引用的所有python对象
    • 1.10 关闭python解释器
  • 2. 调用无参函数示例
  • 3. 调用有参函数示例

1. c语言调用python 的步骤

1.1 包含头文件

#include <Python.h>

1.2 初始化Python解释器

void Py_Initialize();

1.3 添加当前路径到sys.path 中

  • 导入sys模块
使用  PyObject *PyImport_ImportModule(const char *name)  导入
  • 获取sys.path对象
*PyObject_GetAttrString(PyObject *o, const char *attr_name)		获取
  • 将当前路径.添加到sys.path中
int PyList_Append(PyObject *list, PyObject *item)

1.4 导入要调用的模块

PyObject *PyImport_ImportModule(const char *name)

1.5 获取函数对象

PyObject *PyObject_GetAttrString(PyObject *o, const char *attr_name)

1.5.1 检查函数对象是否可被调用

int PyCallable_Check(PyObject *obj)

1.6 构造参数

PyObject *Py_BuildValue(const char *format, ...)

调用此函数创建一个Python元组或者对象作为Python函数的参数,无参数不需要调用。
C和Python的数据类型转换对应的格式:
在这里插入图片描述

1.7 调用函数并获取返回值

PyObject *PyObject_CallObject(PyObject *callable, PyObject *args)

1.8 返回值解析

int PyArg_Parse(PyObject *args, const char *format, ...)

1.9 释放引用的所有python对象

void Py_DECREF(PyObject *o)

1.10 关闭python解释器

void Py_Finalize()

2. 调用无参函数示例

printenv.py

# 无参函数
def fun_noparam():
    print("Hello C")
getpython.c

#include <Python.h>

int main() {
    /*初始化python解释器 */
    Py_Initialize();   

    /* 添加当前路径到sys.path 中 */ 
    // sys模块在Python中提供了对Python解释器的一些变量和功能的访问,例如命令行参数或系统路径等
    PyObject *sys = PyImport_ImportModule("sys");      //从Python的标准库中导入名为sys的模块,并将返回的对象赋值给指针sys
    //从sys模块对象中获取名为path的属性,并将其赋值给指针path。在Python中,sys.path是一个列表,包含了Python解释器在导入模块时会搜索的路径
    PyObject *path = PyObject_GetAttrString(sys, "path"); 
    // 使用`PyUnicode_FromString`函数将C字符串`"."`转换为一个Python的unicode对象。这里的`.`表示当前目录。  
    // 使用`PyList_Append`函数将上述创建的unicode对象添加到`path`列表中。在Python中,这相当于执行`sys.path.append('.'),
    //即将当前目录添加到Python模块的搜索路径中。
    PyList_Append(path, PyUnicode_FromString("."));

    /* 导入要调用的python模块 printenv.py*/
    PyObject *pModel = PyImport_ImportModule("printenv");
    if (!pModel) {
        // 当 Python C API 函数遇到错误时,它们通常会设置一个异常对象,但并不会自动打印错误信息。
        // PyErr_Print() 函数用于检索当前线程中的异常对象,并打印其类型、值和 traceback(如果有的话)。
        PyErr_Print();
        printf("error: load python model faild\n");
        return 1;
    }

    /* 获取导入模块中的函数对象 */ 
    PyObject *pFunc = PyObject_GetAttrString(pModel, "fun_noparam");
    // PyCallable_Check(pFunc) 是 Python C API 中的一个宏,用于检查一个 Python 对象是否可以被调用。
    // 这个宏检查对象是否实现了 Python 的 __call__ 方法,使得它可以像函数那样被调用。
    // pFunc 是一个指向 Python 对象的指针,通常是一个 PyObject* 类型的变量。
    // 这个宏返回一个整数,如果对象是可调用的,返回非零值(通常是 1),否则返回 0。
    if (!pFunc || !PyCallable_Check(pFunc)) {
        PyErr_Print();
        printf("error: python model function fun_noparam() faild\n");
        return 1;
    }

    /* 调用fun_noParam 函数并获取返回值*/
    PyObject *pValue = PyObject_CallObject(pFunc, NULL);
    if (!pValue) {
        PyErr_Print();
        printf("error: function call faild\n");
        return 1;
    }

    /* 释放所有引用的python对象*/
    Py_DECREF(pValue);
    Py_DECREF(pFunc);
    Py_DECREF(pModel);

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

    return 0;
}

编译:

gcc getpython.c -o getpyNoParam -I /usr/include/python3.10 -l python3.10

运行结果:
在这里插入图片描述

3. 调用有参函数示例

parameter.py

# 有参函数
def func_param(param):
    print(param)
    return param
getPythonParam.c

#include <Python.h>

int main() {
    Py_Initialize();

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

    PyObject *pmode = PyImport_ImportModule("parameter");
    if (!pmode) {
        PyErr_Print();
        printf("error: load python model faild\n");
        return 1;
    }

    PyObject *pFunc = PyObject_GetAttrString(pmode, "func_param");
    if (!pFunc || !PyCallable_Check(pFunc)) {
        PyErr_Print();
        printf("error: python model function func_param() faild\n");
        return 1;
    }

    // 创建一个字符串作为函数参数
    char *param = "this c transmit param";
    PyObject *pArgs = Py_BuildValue("(s)", param);   // 构建元组

    // 调用带参python 函数并获取返回值
    PyObject *result = PyObject_CallObject(pFunc, pArgs);
    if (!result) {
        PyErr_Print();
        printf("error: function call faild\n");
    }

    // 将返回类型转为c类型
    char *resultToC = NULL;
    if (!PyArg_Parse(result, "s", &resultToC)) {
        PyErr_Print();
        printf("error: parse return param faild\n");
    }

    // 打印返回值
    printf("return param: %s\n", resultToC);

    /* 释放所有引用的python对象*/
    Py_DECREF(result);
    Py_DECREF(pFunc);
    Py_DECREF(pmode);

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

    return 0;
}

编译:

gcc getpythonParam.c -o getpyParam -I /usr/include/python3.10 -l python3.10

运行结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1630124.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android 在attrs.xml添加属性时出现 Found item Attr/****** more than one time

Android 在attrs.xml添加属性时出现 Found item Attr/****** more than one time 问题描述解决办法方式一方式二 小结 问题描述 在Android应用开发过程中&#xff0c;经常需要自定义控件&#xff0c;并且定义控件的属性&#xff0c;方便灵活的修改控件的显示样式&#xff0c;提…

【CLion】clion无法加载或找不到cmakekists文件

一、问题表象 最近工作中&#xff0c;在git pull远程仓库最新版本程序后&#xff0c;平时打开CLion自动加载的工程CMakeLists文件突然失效&#xff08;显示找不到可编译的文件&#xff09;&#xff0c;无法debug程序。 二、原因分析 基于平时的编码经验和之前git pull也出现…

李沐64_注意力机制——自学笔记

注意力机制 1.卷积、全连接和池化层都只考虑不随意线索 2.注意力机制则显示的考虑随意线索 &#xff08;1&#xff09;随意线索倍称之为查询(query) &#xff08;2&#xff09;每个输入是一个值value&#xff0c;和不随意线索key的对 &#xff08;3&#xff09;通过注意力池…

Oracle集群ORA-03113:end-of-file on communication channel

一、问题场景描述 今天Oracle集群要更新各数据库的数据&#xff0c;折腾的启动不了了&#xff1a; --》数据量比较大&#xff0c;数据泵方式导出的dmp文件 准备导入集群 --》由于之前的生产数据库数据比较少&#xff0c;需要增大表空间。 --》于是在sqlplus命令窗口&#xff0c…

ChatGPT4.0知识问答、DALL-E生成AI图片、Code Copilot辅助编程,打开新世界的大门

目录 1、DALL-E 文字转图片 在线AI修改2、Write For Me3、Code Copilot 目前最强的AI编程大模型4、Diagrams: Show Me5、Instant Website [Multipage] 网站合成神器6、AskYourPDF Research Assistant 无限PDF7、Diagrams & Data: Research, Analyze, Visualize 精读Excel …

kuramoto模型 - 简要介绍

Kuramoto模型源远流长&#xff0c;这里不会对它做过于理论方面的讲解&#xff0c;只是面向动力学重构的工作中&#xff0c;可能要用到Kuramoto模型的相关介绍。 假设读者了解的常微分方程基本概念&#xff0c;图论知识&#xff0c;了解邻接矩阵&#xff0c; 通过本文&#xf…

归并排序详解

目录 归并排序的核心思想&#xff1a; 递归实现&#xff1a; 非递归实现&#xff1a; 时间复杂度&#xff1a; 空间复杂度&#xff1a; 应用场景&#xff1a; 本文全部以升序为例&#xff1a; 归并排序的核心思想&#xff1a; 先分解在合并&#xff1a; 1.归并的归&…

运算符重载(2)

1.赋值运算符重载 #include<iostream> using namespace std;class Person { friend void test01(); public:Person(int age){m_Age new int(age);}/*堆区的数据由程序员手动开辟并手动释放*/~Person(){if (m_Age ! NULL){delete m_Age;}}Person& operator(Person &a…

Python_AI库 Matplotlib的应用简例:绘制与保存折线图

本文默认读者已具备以下技能&#xff1a; 熟悉Python基础语法&#xff0c;以自行阅读python代码块熟悉Vscode或其它编辑工具的应用 在数据可视化领域&#xff0c;Matplotlib无疑是一个强大的工具。它允许我们创建各种静态、动态、交互式的可视化图形&#xff0c;帮助我们更好…

币圈资讯Cryptosquare论坛

在加密货币世界中&#xff0c;信息的及时获取对于投资者和交易者至关重要。今天&#xff0c;我将向大家介绍Cryptosquare这个综合性资讯论坛&#xff0c;它汇集了币圈新闻、空投信息、社会热点以及与Web3相关的工作信息。让我们一起解锁加密世界的种种可能性&#xff0c;探索Cr…

鹏哥C语言复习——字符函数与字符串函数

目录 一.字符函数 1.字符分类函数 2.字符转换函数 二.基础字符串函数 1.strlen函数 2.strcpy函数 3.strcat函数 4.strcmp函数 三.基础字符串函数优化 1.strncpy函数 2.strncat函数 3.strncmp函数 四.进阶字符串函数 1.strstr函数 2.strtok函数 3.strerror函数 一…

Eclipse 如何导入一个 Maven 项目

如果你的项目是 Maven 项目的话&#xff0c;导入的时候需要使用 Import&#xff0c;而不能使用打开项目的方式。 选择导入 选择导入 Maven 项目 然后选择 Maven 项目&#xff0c;开始导入。 选择目录后导入 然后选择你需要导入的目录后&#xff0c;单击导入。 Eclipse 如何导…

Llama-7b-Chinese本地推理

Llama-7b-Chinese 本地推理 基础环境信息&#xff08;wsl2安装Ubuntu22.04 miniconda&#xff09; 使用miniconda搭建环境 (base) :~$ conda create --name Llama-7b-Chinese python3.10 Channels:- defaults Platform: linux-64 Collecting package metadata (repodata.js…

【MySQL精炼宝库】数据库的约束 | 表的设计 | 聚合查询 | 联合查询

目录 一、数据库约束 1.1 约束类型&#xff1a; 1.2 案例演示&#xff1a; 二、表的设计 2.1 一对一: 2.2 一对多: 2.3 多对多: 2.4 内容小结&#xff1a; 三、新增 四、查询 4.1 聚合查询&#xff1a; 4.1.1 聚合函数&#xff1a; 4.1.2 GROUP BY子句&#xff1a…

nginx配置ip_hash负载均衡策略

一、nginx配置ip_hash负载均衡策略 nginx默认的负载均衡策略为轮询&#xff0c;某些场景需要使用ip_hash负载策略&#xff0c;即&#xff1a;同一个ip地址&#xff0c;永远访问nginx后面同一台tomcat。配置示例如下&#xff0c;主要是设置ip_hash&#xff1a; upstream www.ab…

B站美化插件,支持自定义,太酷辣~

大公司的软件和网站通常具有优雅的默认界面设计。 以国内二次元聚集地B站为例&#xff0c;可以说它的UI设计非常吸引人。与其他视频网站繁复的设计相比&#xff0c;B站的界面设计可以说是遥遥领先 然而&#xff0c;总有些人对默认的用户界面感到不满意&#xff0c;他们渴望尝试…

Arm功耗管理精讲与实战

安全之安全(security)博客目录导读 思考 1、为什么要功耗管理&#xff1f;SOC架构中功耗管理示例&#xff1f;功耗管理挑战&#xff1f; 2、从单核->多核->big.LITTLE->DynamIQ&#xff0c;功耗管理架构演进? 3、什么是电压域&#xff1f;什么是电源域&#xff1f…

C#上位机与S7-200Smart通信注意事项

S7-200SMART连接 问题描述 我们使用C#开发上位机和S7-200Smart系列PLC交互数据时&#xff0c;大多会用到Sharp7、Snap7之类的通信类库。有些通信类库默认的使用的是PG连接资源&#xff0c;而对于S7-200Smart来说&#xff0c;它的PG连接资源只有1个。 官网200smart提到的连接数…

smart200 做client,modbus_tcp读取modbus_slave

这里还隐藏一个重要的设置&#xff0c;就是站地址。这个在库函数里。不同plc位置会不一样&#xff0c;我这里是vb1651对应modbus的地址为255&#xff0c;这个值我们可以自己更改&#xff0c;范围为1-247. 打开modbus_slave 软件&#xff0c;

MySQL recursive 递归

MySQL 从最内的select开始执行&#xff0c;但是同一个select clause可以在查询的结果上继续查询。 SELECT menu_id,parent_id,(SELECT m1.parent_id FROM sys_menu AS m1 WHERE m1.menu_idm.parent_id) FROM sys_menu AS m WHERE m.menu_id 89 方案1.通过recursive递归 使用…