c++调用python函数进行传参计算和返回

目录

  • 前言:
  • 配置环境:
  • 基础夯实:
      • 1. 初始化Python解释器
      • 2. 导入Python模块
      • 3. 获取函数对象
      • 4. 调用Python函数
      • 5. 处理返回值
      • 6. 错误处理
      • 7. 资源管理
      • 8. 编译和链接
      • 9. 线程安全性
      • 10. 进一步学习
  • 效果展示:
  • 实现功能:
  • 操作步骤(保姆级教程)
    • 第一步打开VS2022
    • 第二步配置项目python环境
      • 1.添加头文件
      • 2.添加库文件
      • 3.验证配置正确性。
    • 第三步写一个简单的python文件(写的位置易错,需要重点注意)
    • 第四步再VS中添加c++调用python的代码:
  • 参考资料:

前言:

接上一篇python调用c++动态链接库,环境是VS2022和vscode2023
在python中有许多好用的库,比如numpy,opencv,如果你想在c/c++中调用,你就需要进行混合编程。混合编程涉及到了传递参数,接受参数。不同语言的参数还需要使用一个公共的变量进行计算。

配置环境:

编译器:VS2022,vscode2023
python版本:python3.9.6
在这里插入图片描述
在这里插入图片描述

基础夯实:

在C++中调用Python库是一个强大的功能,它允许你结合两种语言的优势:C++的性能和效率,以及Python的丰富库和易用性。要实现这一点,你通常需要使用Python的C API,即Python.h头文件中定义的函数和宏。以下是一些基础知识,帮助你开始在C++中调用Python库。

1. 初始化Python解释器

在任何Python API调用之前,你必须首先初始化Python解释器。这通常通过调用Py_Initialize()函数来完成。在程序的最后,你应该调用Py_Finalize()来清理Python解释器。

#include <Python.h>

int main() {
    Py_Initialize();
    // 你的Python代码调用
    Py_Finalize();
    return 0;
}

2. 导入Python模块

要使用Python库中的函数,你首先需要导入相应的Python模块。这可以通过PyImport_Import()函数完成,它返回一个表示模块的PyObject指针。

PyObject* pModule = PyImport_Import(PyUnicode_FromString("module_name"));
if (!pModule) {
    // 处理错误
}

3. 获取函数对象

一旦导入了模块,你就可以从中获取函数对象了。使用PyObject_GetAttrString()函数,你可以通过函数名获取到函数对象。

PyObject* pFunc = PyObject_GetAttrString(pModule, "function_name");
if (!pFunc || !PyCallable_Check(pFunc)) {
    // 处理错误
}

4. 调用Python函数

要调用Python函数,你需要创建一个包含所有参数的元组,并使用PyObject_CallObject()函数。

PyObject* pArgs = PyTuple_New(arg_count); // arg_count是参数的数量
// 设置元组中的参数值
// 例如:PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", value));

PyObject* pValue = PyObject_CallObject(pFunc, pArgs);
// 检查pValue是否为NULL来处理可能的错误

5. 处理返回值

Python函数的返回值也是一个PyObject指针。你可以根据返回值的类型使用相应的Python API函数来提取值。

if (pValue) {
    // 例如,如果返回值是一个整数,你可以使用PyLong_AsLong()
    long result = PyLong_AsLong(pValue);
    Py_DECREF(pValue); // 不要忘记释放pValue
}

6. 错误处理

在调用Python API时,错误处理是非常重要的。Python API函数通常会返回一个NULL指针来表示错误。你应该检查每个返回值,并在出现错误时适当地处理它。

if (!some_python_function()) {
    // 处理错误,例如使用PyErr_Print()打印错误信息
}

7. 资源管理

在使用Python API时,你会创建很多PyObject对象。为了避免内存泄漏,你应该在不再需要这些对象时调用Py_DECREF()来释放它们。

8. 编译和链接

要编译包含Python API调用的C++代码,你需要确保链接了Python库。这通常意味着在编译命令中添加-lpythonX.Y标志,其中X.Y是你使用的Python版本号。

9. 线程安全性

如果你在多线程环境中使用Python,你需要注意Python的全局解释器锁(GIL)。在调用任何Python API函数之前,你必须确保持有GIL。

10. 进一步学习

Python的C API是非常强大和灵活的,但也可能相当复杂。除了官方文档之外,还有很多教程和示例代码可以帮助你学习如何在C++中调用Python代码。

通过掌握这些基础知识,你就可以开始在C++项目中集成Python库了。随着经验的积累,你将能够更熟练地处理复杂的集成场景。

效果展示:

在这里插入图片描述

实现功能:

实现c++调用python函数,传递参数并进行返回值的接收的效果。

操作步骤(保姆级教程)

第一步打开VS2022

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

// Project1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>

int main()
{
    std::cout << "Hello World!\n";
    system("pause");
}

在这里插入图片描述

第二步配置项目python环境

配置的步骤大致分为两部:
1.VS的项目属性>>配置属性>>C/C++>>添加包含目录中
2.VS的项目属性>>配置属性>>链接器>>附件库目录
3.验证环境安装正确性:

1.添加头文件

1.VS的项目属性>>配置属性>>C/C++>>添加包含目录中
C:\Users\wangningning\AppData\Local\Programs\Python\Python39\include
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最后不要忘记点击确定,确定之后又回到属性界面。相当于把如下文件添加进去:
在这里插入图片描述

2.添加库文件

VS的项目属性>>配置属性>>链接器>>附件库目录>>(参考路径)
C:\Users\wangningning\AppData\Local\Programs\Python\Python39\libs

在这里插入图片描述
在这里插入图片描述
点击确定之后点击应用。
在这里插入图片描述

3.验证配置正确性。

实验代码:

#include <iostream>  
#include <Python.h>  

在这里插入图片描述

第三步写一个简单的python文件(写的位置易错,需要重点注意)

注意(易出现错误),尽量和我的操作一致。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
将代码填写进去,文件名是fun.py

#fun.py
import numpy as np
def fun1(x,y):
    print("fun1 called with x=",x," and y=",y)
    return x+y

在这里插入图片描述
python环境中没有装numpy的去装一个,直接再vscode的命令行里面输入

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple numpy

第四步再VS中添加c++调用python的代码:

#include <iostream>  
#include <Python.h>  

// 使用标准命名空间  
using namespace std;

int main() {
    Py_Initialize(); // 初始化python解释器  
    if (!Py_IsInitialized()) {
        cerr << "Python interpreter initialization failed." << endl;
        return -1;
    }

    PyObject* pName, * pModule, * pFunc, * pArgs; // 定义python对象  

    pName = PyUnicode_FromString("fun"); // 模块名应该是fun,因为文件名是fun.py  
    pModule = PyImport_Import(pName); // 载入fun模块  
    if (!pModule) {
        cerr << "Can't find fun.py" << endl;
        Py_DECREF(pName);
        Py_Finalize();
        return -1;
    }

    // 获取函数对象  
    pFunc = PyObject_GetAttrString(pModule, "fun1"); // 要调用的函数是fun1  
    if (!pFunc || !PyCallable_Check(pFunc)) {
        cerr << "Cannot find function 'fun1'" << endl;
        Py_DECREF(pName);
        Py_DECREF(pModule);
        Py_Finalize();
        return -1;
    }

    // 准备调用fun1函数,它需要两个参数  
    pArgs = PyTuple_New(2); // 创建一个元组,长度为2  
    PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 5)); // 将第一个参数设置为整数5  
    PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 10)); // 将第二个参数设置为整数10  

    // 调用fun1函数  
    PyObject* pValue = PyObject_CallObject(pFunc, pArgs);
    if (pValue != nullptr) {
        // 处理返回值(如果需要)  
        cout << "Function returned: " << PyLong_AsLong(pValue) << endl;
        Py_DECREF(pValue);
    }
    else {
        cerr << "Function call failed." << endl;
    }

    // 销毁python相关对象  
    Py_DECREF(pName);
    Py_DECREF(pModule);
    Py_DECREF(pArgs);
    Py_DECREF(pFunc);

    Py_Finalize();
    system("pause"); // 等待用户输入
    return 0;
}

在这里插入图片描述

我们发现c++成功调用了python的代码,对c++传递的参数进行计算,同时c++对于python返回的结果进行接收。本人也是在技术中学习,欢迎指正文章中的问题,共同进步。

参考资料:

https://zhuanlan.zhihu.com/p/146659551

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CentOS上使用Mosquitto实现Mqtt主题消息发布和订阅mqtt主题消息连同时间戳记录到文件

场景 CentOS上使用rpm离线安装Mosquitto(Linux上Mqtt协议调试工具)附资源下载&#xff1a; CentOS上使用rpm离线安装Mosquitto(Linux上Mqtt协议调试工具)附资源下载-CSDN博客 上面介绍了mosquitto的离线安装。 如果业务场景中需要订阅某mqtt主题的消息并将收到消息的时间以…

Android轻量级RTSP服务使用场景分析和设计探讨

技术背景 好多开发者&#xff0c;对我们Android平台轻量级RTSP服务模块有些陌生&#xff0c;不知道这个模块具体适用于怎样的场景&#xff0c;有什么优缺点&#xff0c;实际上&#xff0c;我们的Android平台轻量级RTSP服务模块更适用于内网环境下、对并发要求不高的场景&#…

Activiti7《第九式:破气式》——流畅驱动工作流进程。面试题大全

冲冲冲&#xff01;开干 这篇文章将分为九个篇章&#xff0c;带你逐步掌握工作流的核心知识。“破气式”&#xff0c;代表着工作流中的 无形之力&#xff0c;它是贯穿整个流程的 关键驱动 不知不觉已经到了独孤九剑最后一式了&#xff0c;我相信到这里之后各位都已经出神入化…

windows桌面管理软件推荐:一键整理桌面!美化电脑桌面小助手!

windows桌面管理软件推荐来咯&#xff01;在繁忙的工作和生活中&#xff0c;一个整洁、有序的电脑桌面不仅能提升工作效率&#xff0c;还能带来愉悦的视觉体验。然而&#xff0c;随着文件的增多&#xff0c;桌面往往变得杂乱无章。幸运的是&#xff0c;市面上有许多优秀的Windo…

构建高可用和高防御力的云服务架构第五部分:PolarDB(5/5)

引言 云计算与数据库服务 云计算作为一种革命性的技术&#xff0c;已经深刻改变了信息技术行业的面貌。它通过提供按需分配的计算资源&#xff0c;使得数据存储、处理和分析变得更加灵活和高效。在云计算的众多服务中&#xff0c;数据库服务扮演着核心角色。数据库服务不仅负…

​地质图制图规范大全资料分享

我们在《2024年最新测绘地理信息规范在线查看下载》一文整理460个测绘地理信息相关规范的在线查看链接。 现在我们又整理了地质图制图规范大全分享给大家&#xff0c;你可以在文末查看该文档的领取方法。 地质图制图规范大全 这些地质图制图规范来自地质科学数据出版系统&am…

Rustrover2024.2 正式发布:个人非商用免费,泰裤辣

如果这个世界本身 已经足够荒唐 那究竟什么才能算是疯狂 爱情就是这样 一旦错过了 就会有另一个人代替 我们知道 jetbrains 在今年的早些时候正式为 rust 语言发布了专用的 IDE &#xff0c;也就是 rustrover。如今 rustrover 也正式跻身为 jetbrains IDE 系列的一员猛将。…

network request to https://registry.npmjs.org/xxx failed, reason: connect ETIM

目录&#xff1a; 1、问题描述2、解决方案3、npm镜像仓库替换 1、问题描述 npm install 时&#xff0c;报错&#xff1a;npm ERR! network request to https://registry.npmjs.org/postcss-pxtorem failed, reason: connect ETIMEDOU npm ERR! code ETIMEDOUT npm ERR! errno…

COMTRADE 录波文件 | 可视化工具 | 电能质量查看软件

COMTRADE 录波文件 | 可视化工具 | 电能质量查看软件 主要功能介绍 支持 IEEE Std C37.111-1991/1999/2013 规范。读取 ASCII 或二进制 COMTRADE 文件。查看来自 COMTRADE 配置文件的模拟和数字通道列表。将图表导出为 SVG、BMP、JPEG 和 PNG 图形格式。将显示的观察结果以 C…

携手长江存储,构建高性能分布式存储

近年来&#xff0c;《金融科技&#xff08;FinTech&#xff09;发展规划&#xff08;2022-2025 年&#xff09;》《关于银行业保险业数字化转型的指导意见》《金融标准化“十四五”发展规划》等金融监管政策陆续出台&#xff0c;金融机构对于数据基础设施的升级部署&#xff0c…

工业建模设计软件概览与SOLIDWORKS深度解析

在当今快速发展的工业领域&#xff0c;高效的建模设计软件是工程师和设计师不可或缺的工具。这些软件不仅提高了设计的精确度&#xff0c;还大幅缩短了产品从概念到市场的周期。本文将为您介绍当前市场上主流的工业建模设计软件&#xff0c;并重点介绍SOLIDWORKS的优势和应用。…

10.软件工程知识详解上

软件工程概述 软件开发生命周期 软件定义时期&#xff1a;包括可行性研究和详细需求分析过程&#xff0c;任务是确定软件开发工程必须完成的总目标&#xff0c;具体可分成问题定义、可行性研究、需求分析等。软件开发时期&#xff1a;就是软件的设计与实现&#xff0c;可分成…

汽车总线之----FlexRay总线

Introduction 随着汽车智能化发展&#xff0c;车辆开发的ECU数量不断增加&#xff0c;人们对汽车系统的各个性能方面提出了更高的需求&#xff0c;比如更多的数据交互&#xff0c;更高的传输带宽等。现如今人们广泛接受电子功能来提高驾驶安全性&#xff0c;像ABS防抱死系统&a…

git push出错Push cannot contain secrets

报错原因&#xff1a; 因为你的代码里面包含了github token明文信息&#xff0c;github担心你的token会泄漏&#xff0c;所以就不允许你推送这些内容。 解决办法&#xff1a; 需要先把代码里面的github token信息删除掉&#xff0c;并且删掉之前的历史提交&#xff0c;只要包…

关于ShuffleNetV1中的channel shuffle操作【代码分析】

1. 官方给出的代码 旷视科技在自己的开源GitHub上给出的channel shuffle相关代码如下图所示&#xff1a; 分析上图中的代码&#xff0c;旷视科技将channel shuffle这个操作视为一个函数&#xff0c;函数传入的参数是输入张量x&#xff0c;x的shape为(batchsize, num_ch…

Ceph 基本架构(一)

Ceph架构图 Ceph整体组成 Ceph 是一个开源的分布式存储系统&#xff0c;设计用于提供优秀的性能、可靠性和可扩展性。Ceph 的架构主要由几个核心组件构成&#xff0c;每个组件都有特定的功能&#xff0c;共同协作以实现高可用性和数据的一致性。 以下是 Ceph 的整体架构及其…

大数据处理从零开始————3.Hadoop伪分布式和分布式搭建

1.伪分布式搭建&#xff08;不会用&#xff0c;了解就好不需要搭建&#xff09; 这里接上一节。 1.1 伪分布式集群概述 伪分布式集群就是只有⼀个服务器节点的分布式集群。在这种模式中&#xff0c;我们也是只需要⼀台机器。 但与本地模式不同&#xff0c;伪分布式采⽤了分布式…

新手操作指引:快速上手腾讯混元大模型

引言 腾讯混元大模型是一款功能强大的AI工具&#xff0c;适用于文本生成、图像创作和视频生成等多种应用场景。对于新手用户&#xff0c;快速上手并充分利用这一工具可能会有些挑战。本文将提供详细的新手操作指引&#xff0c;帮助您轻松开始使用腾讯混元大模型。 步骤一&…

计算机毕业设计 基于Python内蒙古旅游景点数据分析系统 Django+Vue 前后端分离 附源码 讲解 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

006——队列

目录 队列&#xff1a; 单端队列&#xff1a; 存储结构&#xff1a; 顺序队列 思路1&#xff1a;r指针指向尾元素的下一个位置 思路2&#xff1a;r指针指向真正的尾元素 如何解决假溢出的问题&#xff1f; 链式队列 双端队列 存储方式&#xff1a; 顺式存储 代码案例…