C++调用有依赖库的python函数(VS2017+WIN10+Anaconda虚拟环境)

情况1.在写的函数中依赖了能够pip的库,例如numpy库、torch库,见下面的函数:

在这里插入图片描述

import numpy as np
import torch
def add1(a, b):# 确保a和b都是NumPy数组a_array = np.array(a) if not isinstance(a, np.ndarray) else ab_array = np.array(b) if not isinstance(b, np.ndarray) else b# 执行加法操作result = a_array + b_arrayreturn result  # 返回结果
def add2(a, b):# 确保a和b都是PyTorch的张量a_tensor = torch.tensor(a) if not torch.is_tensor(a) else ab_tensor = torch.tensor(b) if not torch.is_tensor(b) else b# 执行加法操作result = a_tensor + b_tensorreturn result  # 返回结果
Step1. 在VS2017中新建项目,并配置环境,参见我的另一篇博文环境配置
Step2. 直接将该函数文件即hello.py放进源.cpp相同的位置

在这里插入图片描述

Step3. 源.cpp中的代码如下,记得改为自己要调用的文件名和函数名
#include <Python.h>
#include<iostream>using namespace std;int main()
{//需要进行强制类型转换//否则报错“void Py_SetPythonHome(wchar_t *)”: 无法将参数 1 从“const wchar_t [44]”转换为“wchar_t *”	Py_SetPythonHome((wchar_t*)L"C:\\software\\Anaconda\\envs\\pytorch"); //Python.exe所在的位置,自己虚拟环境的文件夹下Py_Initialize();//使用python之前,要调用Py_Initialize();这个函数进行初始化if (!Py_IsInitialized()){printf("初始化失败!");return 0;}else {PyRun_SimpleString("import sys");PyRun_SimpleString("sys.path.append('./')");//这一步很重要,修改Python路径PyObject * pModule = NULL;//声明变量PyObject * pFunc = NULL;// 声明变量pModule = PyImport_ImportModule("hello");//这里是要调用的文件名hello.pyif (pModule == NULL){cout << "没找到该Python文件" << endl;}else {pFunc = PyObject_GetAttrString(pModule, "add1");//这里是要调用的函数名PyObject* args = Py_BuildValue("(ii)", 28, 103);//给python函数参数赋值PyObject* pRet = PyObject_CallObject(pFunc, args);//调用函数int res = 0;PyArg_Parse(pRet, "i", &res);//转换返回类型cout << "res:" << res << endl;//输出结果}Py_Finalize();//调用Py_Finalize,这个根Py_Initialize相对应的。}return 0;
}
Step4. 调试即可成功

在这里插入图片描述

情况2.在写的函数中依赖了自己写的另一个文件中的函数,见下面的函数:

在这里插入图片描述

自己在pre_func.py中写了一个Predict函数,依赖了另一个自己写的文件utils_fun.py中的函数
Step1. 在VS2017中新建项目,并配置环境,参见我的另一篇博文环境配置
Step2. 将这两个函数文件都放进源.cpp相同的位置,见下图

在这里插入图片描述

Step3. 源.cpp中仅需要给定predict函数需要的参数即可,给大家参考一下我的源.cpp中的代码内容,我的predict函数需要6个字符串参数(大家在用时仅需要改为自己的文件名称和函数名称并修改自己的参数即可,框架通用)
#include <Python.h>
#include<iostream>using namespace std;int main()
{//需要进行强制类型转换//否则报错“void Py_SetPythonHome(wchar_t *)”: 无法将参数 1 从“const wchar_t [44]”转换为“wchar_t *”	Py_SetPythonHome((wchar_t*)L"C:\\software\\Anaconda\\envs\\pytorch");Py_Initialize();//使用python之前,要调用Py_Initialize();这个函数进行初始化if (!Py_IsInitialized()){printf("初始化失败!");return 0;}else {PyRun_SimpleString("import sys");PyRun_SimpleString("sys.path.append('./')");//这一步很重要,修改Python路径PyObject * pModule = NULL;//声明变量PyObject * pFunc = NULL;// 声明变量pModule = PyImport_ImportModule("pre_func");//这里是要调用的文件名hello.pyif (pModule == NULL){cout << "没找到该Python文件" << endl;}else {pFunc = PyObject_GetAttrString(pModule, "predict");//这里是要调用的函数名// 转换C++字符串为Python可以接受的格式PyObject* model_path = PyUnicode_FromString("C:\\Users\\admin\\Desktop\\test\\best_model.pth");PyObject* train_input_dir = PyUnicode_FromString("C:\\Users\\admin\\Desktop\\data\\train\\input\\16_Electrode");PyObject* train_output_dir = PyUnicode_FromString("C:\\Users\\admin\\Desktop\\data\\train\\output\\Output_16");PyObject* pre_input_dir = PyUnicode_FromString("C:\\Users\\admin\\Desktop\\data\\predict");PyObject* destination_path = PyUnicode_FromString("C:\\Users\\admin\\Desktop\\test\\result");PyObject* is_cnn = PyUnicode_FromString("no");// 检查是否成功创建了Python字符串对象if (!model_path || !train_input_dir || !train_output_dir || !pre_input_dir || !destination_path || !is_cnn) {cout << "无法创建Python字符串对象" << endl;Py_XDECREF(model_path);Py_XDECREF(train_input_dir);Py_XDECREF(train_output_dir);Py_XDECREF(pre_input_dir);Py_XDECREF(destination_path);Py_XDECREF(is_cnn);Py_Finalize();return 1;}// 将所有参数放入一个元组中PyObject* pArgs = PyTuple_Pack(6,model_path, train_input_dir, train_output_dir, pre_input_dir, destination_path, is_cnn);// 调用Python函数PyObject* pValue = PyObject_CallObject(pFunc, pArgs);// 检查Python函数是否返回if (pValue != NULL) {// 处理返回值// 这里可以根据需要处理返回值,例如打印它printf("预测函数执行成功。\n");Py_DECREF(pValue);}else {// 打印错误信息并清理PyErr_Print();cout << "调用Python函数predict失败" << endl;}// 清理Python对象Py_XDECREF(pModule);Py_XDECREF(pFunc);Py_XDECREF(pArgs);Py_XDECREF(model_path);Py_XDECREF(train_input_dir);Py_XDECREF(train_output_dir);Py_XDECREF(pre_input_dir);Py_XDECREF(destination_path);Py_XDECREF(is_cnn);}Py_Finalize();//调用Py_Finalize,这个根Py_Initialize相对应的。}return 0;
}
Step4.调试即可成功

在这里插入图片描述
PS:在用torch.load()加载pth文件时,如果函数名改过,一定要重新生成一遍pth,否则c++会报错,错误为ModuleNotFoundError: No module named ‘xxxx’,xxxx为你之前的函数名

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

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

相关文章

萤火虫优化算法(Firefly Algorithm)

注意&#xff1a;本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 &#xff08;[www.aideeplearning.cn]&#xff09; 算法背景 萤火虫优化算法&#xff0c;是由剑桥大学的Xin-She Yang在2009年提出的一种基于群体智能的优化算法。它的灵感来源于萤火虫在夜晚闪烁…

Blender细节补充

1.饼状菜单&#xff0c;用于快速切换/选择 例如&#xff1a; ~&#xff1a;切换视图 Z&#xff1a;切换着色方式 &#xff0c;&#xff1a;切换坐标系 .&#xff1a;切换基准点 Shift S&#xff1a;吸附 有两种使用方式&#xff1a; -点选 -滑选&#xff0c;按快捷键…

表的创建与操作表

1. 创建表 创建表有两种方式 : 一种是白手起家自己添&#xff0c;一种是富二代直接继承. 2. 创建方式1 (1). 必须具备条件 CREATE TABLE权限存储空间 (2). 语法格式 CREATE TABLE IF NOT EXISTS 表名(字段1, 数据类型 [约束条件] [默认值],字段2, 数据类型 [约束条件] [默…

node pnpm修改默认包的存储路径

pnpm与npm的区别 PNPM和NPM是两个不同的包管理工具。 NPM&#xff08;Node Package Manager&#xff09;是Node.js的官方包管理工具&#xff0c;用于安装、发布和管理Node.js模块。NPM将包安装在项目的node_modules目录中&#xff0c;每个包都有自己的依赖树。 PNPM&#xf…

从0开发、发布油猴脚本(保姆级)

概览 项目中使用conify集成图标&#xff0c;有些内网用户只能使用离线图标&#xff0c;但是如何判断使用的conify集成图标是在线还是离线呢&#xff1f;这个时候就需要一个油猴脚本&#xff0c;作用于iconify官网&#xff0c;对离线图标进行标识。 此篇文章主要从如下几点去梳…

MySQL数据库的初始化(创建库、创建表、向数据库添加测试数据)

MySQL数据库的初始化&#xff08;创建库、创建表、向数据库添加测试数据&#xff09; MySQL数据库简介MySQL创建一个新的数据库MySQL创建一张新的数据表简单&#xff08;设置&#xff09;表复杂&#xff08;设置&#xff09;表 填充测试数据SQL语句mysql>模式下输入的每句sq…

现代信号处理9_正则化(CSDN_20240512)

正则化的引入 解线性方程组&#xff1a; 这项工作有很多种做法&#xff0c;下面介绍两种&#xff0c;如下图所示&#xff0c;有一些数据点需要拟合&#xff0c;拟合的方法有很多。 1&#xff09; 构造线性函数①&#xff0c;这种函数比较简单&#xff0c;此时 2&#xff09; 构…

跟TED演讲学英文:Why US politics is broken — and how to fix it by Andrew Yang

Why US politics is broken — and how to fix it Link: https://www.ted.com/talks/andrew_yang_why_us_politics_is_broken_and_how_to_fix_it? Speaker: Andrew Yang Date: April 2024 文章目录 Why US politics is broken — and how to fix itIntroductionVocabularyTr…

wordpress主题 7B2 PRO主题5.4.2免授权直接安装

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 WordPress 资讯、资源、社交、商城、圈子、导航等多功能商用主题&#xff1a;B2 PRO 其设计风格专业且时尚&#xff0c;功能十分强大&#xff0c;包括多栏布局、自定义页面、强大的主…

【JavaEE网络】HTTPS详解:从对称与非对称加密到证书认证

目录 HTTPSHTTPS 是什么“加密” 是什么HTTTPS 的工作过程引入对称加密引入非对称加密引入证书完整流程总结 HTTPS HTTPS 是什么 HTTPS 也是一个应用层协议. 是在 HTTP 协议的基础上引入了一个加密层. HTTP 协议内容都是按照文本的方式明文传输的. 这就导致在传输过程中出现…

LeetCode - 0088 合并两个有序数组

题目地址&#xff1a;https://leetcode.cn/problems/merge-sorted-array/description/ 引言&#xff1a;话接上回&#xff0c;由于上次面试官着急下班&#xff0c;面试不得不提前终止&#xff0c;这不&#xff0c;他又找我去面试了 面试官&#xff1a;你好&#xff0c;小伙子&a…

C++入门——命名空间、缺省参数、函数重载、引用、内敛函数、auto关键字

目录 前言 一、什么是C 1.1 C关键字(C98) 二、命名空间 2.1 命名空间定义 1.正常命名空间的定义 2.命名空间的定义可以嵌套 3.同名的命名空间会合并 2.2 命名空间的使用 三、C输入&输出 四、缺省参数 4.1 缺省参数概念 4.2 缺省参数分类 五、函数重载 5.1 …

Springboot集成Netflix-ribbon、Enreka实现负载均衡-12

Netflix Ribbon简介 Netflix Ribbon是Netflix发布的云中间层服务开源项目&#xff0c;主要功能是提供客户端的软件负载均衡算法&#xff0c;将Netflix的中间层服务连接在一起。 具体来说&#xff0c;Ribbon是一个客户端负载均衡器&#xff0c;可以在配置文件中列出所有的服务…

PostgreSQL的学习心得和知识总结(一百四十三)|深入理解PostgreSQL数据库之Support event trigger for logoff

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…

VirtualBox7安装ubantu server 22.04通过NAT+Only-Host双网卡实现宿主机与虚拟机互通

目录 背景环境安装虚拟机配置网卡修改ssh端口遇到的坑参考文章 背景 时间长没用docker了&#xff0c;有些命令都快忘了&#xff0c;心血来潮想着搞个docker玩一玩&#xff0c;所以需要先搞一个虚拟机&#xff0c;因为之前CentOS用的比较多&#xff0c;所以这次想试一试ubantu。…

openlayers实现绘制图标,并实现图标的聚合功能

点聚合说明 点聚合功能是指将地图上密集的点数据聚合成一个更大的点或者其他形状&#xff0c;以改善地图的可视化效果和性能。点聚合功能通常用于在地图上显示大量的点标记&#xff0c;例如地图上的POI&#xff08;兴趣点&#xff09;、传感器数据等。通过点聚合功能&#xff…

[单机]成吉思汗3_GM工具_VM虚拟机

稀有端游成吉思汗1,2,3单机版虚拟机一键端完整版 本教程仅限学习使用&#xff0c;禁止商用&#xff0c;一切后果与本人无关&#xff0c;此声明具有法律效应&#xff01;&#xff01;&#xff01;&#xff01; 教程是本人亲自搭建成功的&#xff0c;绝对是完整可运行的&#x…

[算法][数组][leetcode]2391. 收集垃圾的最少总时间

题目地址: https://leetcode.cn/problems/minimum-amount-of-time-to-collect-garbage/description/ 题解&#xff1a; class Solution {public int garbageCollection(String[] garbage, int[] travel) {int ans 0;//先计算收所有的垃圾需要多少时间for(String s :garbage){…

D - Another Sigma Problem(ABC)

思路&#xff1a;我们可以处理一个后缀来记录当前数a[i]需要乘上多少&#xff08;类似于1110这样的&#xff09;&#xff0c;然后对于当前位来说&#xff0c;对答案的贡献还要加上(i - 1) * a[i]&#xff0c;因为a[i]还要做前(i - 1)个数的后缀。 代码&#xff1a; #include &…

【详细介绍下Visual Studio】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…