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

news2024/9/25 23:22:47

在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 sys

def 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.coloradmin.cn/o/1533670.html

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

相关文章

Ubutun部署docker,并使用docker部署springboot项目,关闭软件可继续访问

工具为xftp和xshell。 我这里使用的Ubuntu的版本是20.04的&#xff0c;话不多说&#xff0c;我们来直接上代码。 首先我们最好使用管理员权限进行操作&#xff0c;预防操作时遇到权限问题。 部署docker 登入管理员 不登入管理员也没关系。 su根据提示输入密码&#xff0c;进…

nginx使用与配置文件

nginx服务配置与配置优化 nginx服务脚本配置 mkdir wwwroot cd wwwroot/ mkdir nginx1 touch index.php vim index.php<?php echo $_SERVER["REMOTE_ADDR"]; ​ ​ vim conf/nginx.confserver {listen 80;server_name localhost;root /www/wwwroot/nginx…

【100%成功】从0到1教你开通GPT4.0会员,一年立省1800,拒绝高价代开,免排队无需等待。

我们看下这个网址代开差不多要300&#xff0c;而我用Fomepay每个月才150左右&#xff0c;不需要年费月费&#xff0c;虽然有开卡费用10刀&#xff0c;但是也很划算&#xff0c;你自己算一下&#xff0c;一个月300一年就1千多 点击获取卡&#xff0c;0年费0月费 开卡步骤很简…

在任何 Mac 上恢复永久删除照片的 5 种简单方法

Mac 为业余和专业摄影师提供了很多东西&#xff0c;从令人印象深刻的硬件到广泛的照片管理和编辑应用程序。它还提供了多种恢复丢失照片的方法&#xff0c;我们在本文中介绍了其中的五种方法&#xff0c;以帮助您避免潜在的灾难性情况。 Mac 上删除的照片去了哪里&#xff1f;…

大屏页面 电子数字 制作

字体包下载地址 链接: https://pan.baidu.com/s/1pjslpT5QQi7-oALDM-uX8g 提取码: zxcv 效果展示 使用前使用后 使用方式 1.解压后将文件夹放入public 2.在公用样式中加入 font-face {font-family: mFont;src: url(../../public/DS-Digital/DS-DIGI-1.ttf); } 3. 在项目…

深化涉案企业合规改革:从治标到治本的必由之路

在市场经济的大潮中&#xff0c;企业作为经济发展的主体&#xff0c;其健康运行对整个社会的稳定与繁荣至关重要。然而&#xff0c;随着经济全球化的加速和市场竞争的激烈&#xff0c;一些企业在追求利润最大化的过程中&#xff0c;可能会忽视法律法规&#xff0c;甚至触犯法律…

机器学习知识点复习 下(保研、复试、面试)百面机器学习笔记

机器学习知识点复习下 第八章、采样1.采样的作用 第九章、前向神经网络1.多层感知机与布尔函数2.神经网络中的激活函数3.多层感知机的反向传播算法4.神经网络训练技巧5.深度卷积神经网络6.深度残差网络 第十章、循环神经网络1.循环神经网络和卷积神经网络2.循环神经网络的梯度消…

RustDesk 快速部署,搭建自己的“向日葵”

前言&#xff1a;为什么要搭建自己的远程控制 一直都是用向日葵来做远程控制和一些运维服务提供&#xff0c;but经常性卡出翔&#xff0c;时好时坏&#xff0c;所以萌生了搭建一套自己的远程控制的软件。到目前远程控制的服务器和设置已经搭建完毕&#xff0c;高级的自编译客户…

【Selenium】隐藏元素的定位和操作

一、selenium 中隐藏元素如何定位&#xff1f; 如果单纯的定位的话&#xff0c;隐藏元素和普通不隐藏元素定位没啥区别&#xff0c;用正常定位方法就行了 但是吧~~~能定位到并不意味着能操作元素&#xff08;如click,clear,send_keys&#xff09; 二、隐藏元素 如下图有个输入框…

如何在 Postman 中执行断言测试?

在当今的软件构建流程中&#xff0c;应用程序编程接口&#xff0c;简称 API&#xff0c;起到了不可或缺的作用&#xff0c;它们使得不同的软件应用能够互相沟通和交换数据。随着应用程序的不断演进变得越发复杂&#xff0c;保障API的可靠性及其稳定性显得格外关键。正因如此&am…

ARM64汇编08 - 块访存指令

armv8 里面似乎没有了 v7 中的块访存指令&#xff0c;就是一次性访问一块内存的指令。我们还是先介绍下 v7 中的块访存指令。 V7中的块访存指令​ 手册中介绍了很多种该指令的变种形式&#xff0c;其实了解了这个指令的英文含义就都很好理解。 LD - load&#xff0c;加载 M …

C++:部分题目

1. 封装、继承、多态 封装&#xff1a;将所需的数据成员&#xff0c;以及对数据的操作方法&#xff08;成员函数&#xff09;&#xff0c;绑定在一起成为类&#xff08;类型&#xff09;&#xff0c;定义该类型的对象时&#xff0c;成员被自动隐藏在对象内部。通过封装可以限定…

SOLIDWORKS Simulation子模型分析的使用方法

子模型介绍 SOLIDWORKS Simulation的子模型基于圣维南原理。对于一个比较复杂的模型&#xff0c;如果想升级局部的应力计算精度&#xff0c;就需要对整个模型的网格进行调整并重新进行计算&#xff0c;整个过程耗时较长而且不容易得到满意的结果。 SOLIDWORKS Simulation的子…

【深度学习】训练Stable Diffusion环境

仓库&#xff1a; https://github.com/bmaltais/kohya_ss.git 基础镜像&#xff1a; from kevinchina/deeplearning:sdxllighting_trt_nginx_002api docker run --net host --gpus device0 -e APIWORKS1 -it t1:t1 bash构建环境&#xff1a; sudo -i git clone https://git…

面试常问:为什么 Vite 速度比 Webpack 快

前言 最近作者在学习 webpack 相关的知识&#xff0c;之前一直对这个问题不是特别了解&#xff0c;甚至讲不出个123....&#xff0c;这个问题在面试中也是常见的&#xff0c;作者在学习的过程当中总结了以下几点&#xff0c;在这里分享给大家看一下&#xff0c;当然最重要的是…

【MySQL配置】Windows环境下载并安装MySQL数据库(内含图片,保姆级指引)

一、下载自身所需Mysql 官网链接&#xff1a;https://dev.mysql.com/downloads/installer/ 点击Download后&#xff0c;跳转如下页面。你可以点击注册一个谷歌账号(不是硬性要求)&#xff0c;或者直接如图开始下载。 二、安装所下载的版本 1、双击下载的MySQL文件 2、选择…

深入理解与实践AB测试:从理论到实战案例解析

一、引言 在互联网产品优化和运营策略制定中&#xff0c;AB测试&#xff08;也称为分组测试或随机化对照实验&#xff09;是一种科学且严谨的方法。它通过将用户群体随机分配至不同的实验组&#xff08;通常是A组和B组&#xff09;&#xff0c;对比不同版本的产品或策略对关键…

MySQl基础入门⑫

上一遍文章内容 查询时选择行 1.查询指定记录 假设students表包含字段name, major, 和 email&#xff0c;我们可以构造一个查询来找出所有专业为“计算机科学”且邮箱中包含"university.edu"的学生姓名和邮箱&#xff1a; SELECT name, email FROM students WHER…

种植新革命:科技赋能绿色未来

《种植新革命&#xff1a;科技赋能绿色未来》 一、种植技术的颠覆式创新 随着科技的飞速发展&#xff0c;种植技术也在经历一场颠覆式的创新。传统的种植方式&#xff0c;虽然历史悠久&#xff0c;经验丰富&#xff0c;但在面对现代化、大规模、高效的需求时&#xff0c;逐渐…

一分钟带你入门Selenium入门!【建议收藏】

Selenium入门 欢迎阅读Selenium入门讲义&#xff0c;本讲义将会重点介绍Selenium的入门知识以及Selenium的前置知识。 自动化测试的基础 在Selenium的课程以前&#xff0c;我们先回顾一下软件测试的基本原理&#xff0c;为我们进一步完成Selenium自动化测试做好准备。 软件…