在Linux环境底下 用C语言执行Python程序

在Linux环境底下 用C语言执行Python程序

文章目录

  • 在Linux环境底下 用C语言执行Python程序
    • 1、环境安装&检测
    • 2、C语言调用Python语句
      • 2.1 直接调用python语句
      • 2.2 调用无参python函数
      • 2.3 调用有参python函数

1、环境安装&检测

  • 通过C语言调用Python代码,需要先安装libpython3的 dev依赖库(不同的ubuntu版本下,python版本 可能会有差异, 比如ubuntu 22.04里是libpython3.10-dev)。

  • 首先可以通过以下命令验证是否是否已经存在python3的dev包

  • dpkg -l | grep libpython3

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

    pg@pg-Default-string:~$ dpkg -l | grep libpythonii libpython3-dev:amd64 3.10.6-1~22.04
    amd64 header files and a static library for Python (default)
    ii libpython3-stdlib:amd64 3.10.6-1~22.04 amd64 interactive high-level object-oriented language (default python3 version)
    ii libpython3.10:amd64 3.10.12-1~22.04.2 amd64 Shared Python runtime library (version 3.10)
    ii libpython3.10-dev:amd64 3.10.12-1~22.04.2 amd64 Header files and a static library for Python (v3.10)
    ii libpython3.10-minimal:amd64 3.10.12-1~22.04.2 amd64 Minimal subset of the Python language (version 3.10)
    ii libpython3.10-stdlib:amd64 3.10.12-1~22.04.2 amd64 Interactive high-level object-oriented language (standardlibrary, version 3.10)
    

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

    sudo apt install libpython3.10-dev
    Orangepi Zero2 //全志H616开发学习文档 
    

2、C语言调用Python语句

2.1 直接调用python语句

  • 我们先来一个简单的例子
// simpledemo.c
#include "Python.h"
int main()
{Py_Initialize(); // 初始化//int PyRun_SimpleString(const char *command)PyRun_SimpleString("print ('funny')");Py_Finalize(); //释放资源; 最后在程序结束时使用Py_Finalize()函数关闭Python解释器,并释放资源
}

然要编译和运行这个程序,可以使用以下命令(假设使用的是gcc编译器和Python 3.10版本):

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

–>正常输出

funny

2.2 调用无参python函数

  • 上文调用了print (‘funny’)这条语句,现在把这条语句放到 nopara.py的文件的函数里, 如下
#nopara.py文件
def say_funny():print('funny')

接下来用C语言进行调用,注意文件后缀。

//nopara.c
#if 0
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解释器。
相关的函数参数说明参考网站(网站左上角输入函数名即可开始搜索):
https://docs.python.org/zh-cn/3/c-api/import.html
#endif#include <Python.h>
int main()
{Py_Initialize();//创建新的python环境,加载所有内置模块和扩展模块,-->c中执行py// 将当前路径添加到sys.path中PyObject *sys = PyImport_ImportModule("sys");PyObject *path = PyObject_GetAttrString(sys, "path");//获取引用PyList_Append(path, PyUnicode_FromString("."));//将当前路径.添加到sys.path中,以便加载当前的Python模块(Python文件即python模块)。// 导入nopara模块PyObject *pModule = PyImport_ImportModule("nopara");if (!pModule){PyErr_Print();printf("ERROR: failed to load nopara.py\n");return 1;}// 获取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;}// 调用say_funny函数并获取返回值PyObject *pValue = PyObject_CallObject(pFunc, NULL);if (!pValue){PyErr_Print();printf("ERROR: function call failed\n");return 1;}// 释放所有引用的Python对象Py_DECREF(pValue);Py_DECREF(pFunc);Py_DECREF(pModule);// 关闭Python解释器Py_Finalize();return 0;
}

要编译和运行这个程序,可以使用以下命令(假设使用的是gcc编译器和Python 3.10版本)

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

–>正常输出

funny

2.3 调用有参python函数

  • C语言调用python有参函数,首先定义一个带参数和返回值的函数
#nopara.py文件
import sysdef say_funny(s):print('funny')return s
# print(sys.path)

接下来用C语言进行调用,调用的流程无参函数的调用方式几乎是一样的是的:

//nopara.c
#if 0
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解释器。
相关的函数参数说明参考网站(网站左上角输入函数名即可开始搜索):
https://docs.python.org/zh-cn/3/c-api/import.html
#endif#include <Python.h>//包含Python.h头文件,以便使用Python API。
int main()
{Py_Initialize();//使用void Py_Initialize()初始化Python解释器,// 将当前路径添加到sys.path中PyObject *sys = PyImport_ImportModule("sys");//初始化python解释器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 nopara.py\n");}//获取say_funny函数对象PyObject *pFunc = PyObject_GetAttrString(pModule, "say_funny");if (!pFunc){PyErr_Print();printf("Error: failed to load say_funny\n");}//创建一个字符串作为参数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");} //将返回值转换为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;
}

这里要注意的是,Py_BuildValue的第一个参数是类型转换:C对应的Python的数据类型转换对应的格式 如下:

C 对应 Python 数据类型格式
在这里插入图片描述
  • 然要编译和运行这个程序,可以使用以下命令(假设使用的是gcc编译器和Python 3.10版本)

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

–>正常输出

funny
pValue=comedy


欢迎大家一起交流讨论!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

matlab 混沌系统李雅普洛夫指数谱相图分岔图和庞加莱界面

1、内容简介 略 65-可以交流、咨询、答疑 2、内容说明 matlab 混沌系统李雅普洛夫指数谱相图分岔图和庞加莱界面 混沌系统李雅普洛夫指数谱相图分岔图和庞加莱界面 李雅普洛夫指数谱、相图、分岔图、庞加莱界面 3、仿真分析 略 4、参考论文 略

Java基础学习笔记三

环境变量CLASSPATH classpath环境变量是隶属于java语言的&#xff0c;不是windows操作系统的&#xff0c;和PATH环境变量完全不同classpath环境变量是给classloader&#xff08;类加载器&#xff09;指路的java A 。执行后&#xff0c;先启动JVM&#xff0c; JVM启动classload…

目标检测---IOU计算详细解读(IoU、GIoU、DIoU、CIoU、EIOU、Focal-EIOU、SIOU、WIOU)

常见IoU解读与代码实现 一、✒️IoU&#xff08;Intersection over Union&#xff09;1.1 &#x1f525;IoU原理☀️ 优点⚡️缺点 1.2 &#x1f525;IoU计算1.3 &#x1f4cc;IoU代码实现 二、✒️GIoU&#xff08;Generalized IoU&#xff09;2.1 GIoU原理☀️优点⚡️缺点 2…

浏览量这么低,还要不要继续坚持?

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 曾经在一个群里聊天&#xff0c;有群友看到我两位数的浏览量&#xff0c;说到&#xff1a;浏览量这么低还坚持什么&#xff1f; 浏览量低是事实&#xff0c;大多数是十几二十的&#xff0c;上百的都是少数&#xff0c…

ros小问题之差速轮式机器人轮子不显示(rviz gazebo)

在rviz及gazebo练习差速轮式机器人时&#xff0c;很奇怪&#xff0c;只有个机器人的底板及底部的两个万向轮&#xff0c;如下图&#xff0c; 后来查看相关.xacro文件&#xff0c;里面是引用包含了轮子的xacro文件&#xff0c;只需传入不同的参数即可调用生成不同位置的轮子&…

QT网络编程之获取本机网络信息

一.概述 查询一个主机的MAC地址或者IP地址是网络应用中常用到的功能&#xff0c;Qt提供了QHostInfo和QNetworkInterface 类可以用于此类信息的查询 1.QHostInfo 类&#xff08;显示和查找本地的信息&#xff09; 2.QNetworkInterface 类&#xff08;获得应用程序上所在主机的…

猜数字游戏有三变(Java篇)

本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

网络原理(3)——TCP协议

目录 一、连接管理 二、三次握手 1、何为三次握手&#xff1f; 2、三次握手有何意义&#xff1f; 三、四次挥手 三次握手和四次挥手的相似之处和不同之处 &#xff08;1&#xff09;相似之处 &#xff08;2&#xff09;不同之处 四、TCP的状态 建立连接&#xff1a; 断开…

docker一键部署若依前后端分离版本

比如这里把文件放到/xin/docker/jiaoZ/的目录下&#xff0c;jar包和下面的配置文件都放在这个文件夹下。 注意要把jar端口改为你实际启动的&#xff0c;映射端口也可以改为你想要的。 这里的映射端口为&#xff1a;nginx监听80端口&#xff0c;jar在8620端口&#xff0c;mysq…

【matlab安装casadi】

虽然安装起来很简单&#xff0c;但是网上没找到好的教程&#xff0c;姑且写一下记录一下 首先到github找到对应的库&#xff1a;https://github.com/casadi/casadi找到发布的版本&#xff0c;点进去 这里就可以点进去下载自己需要的版本了下面也有对应的下载后的安装方式&…

[python] 卡诺图化简

在温故数据合并的时候突然想起数电的 卡诺图. 根据合并一位不同的原则, 使用 python 做了一个实现, 感觉和QM算法不太一样: # 判断两个数是否只有一个二进制不一样 def nor(x1, x2):return x1^x2# 判断两个集合是否相邻, 只有一位不同 def is_track(x1, x2):ts [nor(x1[i],x…

计算机网络——物理层(编码与调制)

计算机网络——编码与调制 基带信号和宽带信号编码与调制数字数据编码为数字信号非归零编码归零编码反向不归零编码曼彻斯特编码差分曼彻斯特编码4B/5B编码 数字数据调制为模拟信号模拟数据编码为数字信号模拟数据调制为模拟信号 我们之前讲了物理层的一些基础知识和两个准则&a…

腾讯云服务器如何购买省钱?2024年优惠券和优惠活动整理

腾讯云代金券领取渠道有哪些&#xff1f;腾讯云官网可以领取、官方媒体账号可以领取代金券、完成任务可以领取代金券&#xff0c;大家也可以在腾讯云百科蹲守代金券&#xff0c;因为腾讯云代金券领取渠道比较分散&#xff0c;腾讯云百科txybk.com专注汇总优惠代金券领取页面&am…

【数据结构】猛猛干11道链表OJ(未完待续ing)

前言知识点 链表的调试技巧 int main() {struct ListNode* n1(struct ListNode*)malloc(sizeof(struct ListNode));assert(n1);struct ListNode* n2(struct ListNode*)malloc(sizeof(struct ListNode));assert(n2);struct ListNode* n3(struct ListNode*)malloc(sizeof(struc…

JVM学习-类加载

目录 1.类文件结构 2.类加载器 3.类加载的三个阶段 3.1加载 3.2链接 3.2.1验证 3.2.2准备阶段 3.2.3解析阶段 3.3初始化 4.拓展&#xff1a;反射 4.1获取类对象 4.2创建实例 4.3获取方法 4.4方法调用 1.类文件结构 2.类加载器 类加载器用来将类文件的二进制字节码加载到JV…

蓝桥杯之简单数论冲刺

文章目录 取模快速幂 取模 这道题目有两个注意点&#xff1a; 1.当你的取模之后刚好等于0的话&#xff0c;后面就不用进行后面的计算 2.if sum detail[i] > q: 这个语句的等号也很重要 import os import sys# 请在此输入您的代码a,b,n map(int,input().split())week a*5 …

代码随想录刷题day29|非递减子序列全排列全排列II

文章目录 day29学习内容一、非递减子序列1.1、代码-错误写法1.1.1 多了一个return语句。1.1.2、nums[i-1] > nums[i]&#xff0c;这个条件写错了&#xff0c;为什么呢&#xff1f;1. 忽略了回溯算法的动态决策过程2. 限制了可能的递增子序列的探索 1.2、代码-正确写法 二、全…

还是了解下吧,大语言模型调研汇总

大语言模型调研汇总 一. Basic Language ModelT5GPT-3LaMDAJurassic-1MT-NLGGopherChinchillaPaLMU-PaLMOPTLLaMABLOOMGLM-130BERNIE 3.0 Titan 二. Instruction-Finetuned Language ModelT0FLANFlan-LMBLOOMZ & mT0GPT-3.5ChatGPTGPT-4AlpacaChatGLMERNIE BotBard 自从Cha…

wayland(xdg_wm_base) + egl + opengles 渲染使用纹理贴图的旋转 3D 立方体实例(十三)

文章目录 前言一、使用 stb_image 库加载纹理图片1. 获取 stb_image.h 头文件2. 使用 stb_image.h 中的相关接口加载纹理图片3. 纹理图片——cordeBouee4.jpg二、渲染使用纹理贴图的旋转 3D 立方体1. egl_wayland_texture_cube.c2. Matrix.h 和 Matrix.c3. xdg-shell-client-pr…

浅谈大模型“幻觉”问题

大模型的幻觉大概来源于算法对于数据处理的混乱&#xff0c;它不像人类一样可以by the book&#xff0c;它没有一个权威的对照数据源。 什么是大模型幻觉 大模型的幻觉&#xff08;Hallucination&#xff09;是指当人工智能模型生成的内容与提供的源内容不符或没有意义的现象。…