C++调用python: VS2017 + Anaconda + pypi第三方库

步骤一:在Anaconda中创建虚拟环境

        这一点对大家来说应该很简单,简单介绍一下,不做过多解释。值得注意的是,要用conda命令创建环境,用pip install配置环境。

conda create -n c_python_env python==3.9 # 用conda创建python虚拟环境
conda activate c_python_env              # 激活该虚拟环境
pip install numpy                        # 在虚拟环境中用pip安装python包

在Anaconda的安装目录下,可以看到如下文件夹,就是我们新创建的环境:

步骤二:在VS2017中,创建一个C++项目: C_Python

        具体过程不再赘述,在项目中创建一个文件“c_python_test.cpp”,添加以下内容:

c_python_test.cpp

#include <Python.h>
#include <iostream>
#include <string>
using namespace std;


int main_()
{	
	//1. 初始化
	Py_Initialize();//使用python之前,要调用Py_Initailize()函数,进行初始化
	if (!Py_IsInitialized)
	{
		printf("初始化失败!!");
		return 0;
	}

	PyRun_SimpleString("print('hello world')");
	PyRun_SimpleString("import numpy as np");

	Py_Finalize();
	system("pause");
	return 0;
}


 步骤三:在VS2017中配置Anaconda创建的python环境

VS2017的设置如下:

        1)在VS的项目属性>>配置属性>>VC++目录>>包含目录中,将Anaconda虚拟环境的根目录下的include文件夹添加进来;

        2)在VS的项目属性>>配置属性>>VC++目录>> 库目录中,将Anaconda虚拟环境的根目录下的libs文件夹添加进来

         3)然后在VS的项目属性>>配置属性>>链接器>>输入>>附加依赖项中,Anaconda虚拟环境的根目录下的libs/python39_d.lib添加上。如果没有python39_d.lib文件,就把python39.lib复制一份,重命名为python39_d.lib。

 4)拷贝Anaconda虚拟环境的根目录下的“DLLs”和“Lib”两个文件夹复制到exe所在文件夹(x64/Release)。没有exe文件夹就先编译生成一个。这一步很重要,否则C++无法找到虚拟环境中的第三方依赖库,比如我们上面安装的numpy库。

     

拷贝到

      

        5)如果有必要,把Anaconda虚拟环境中的python3.lib、python39.lib和python39_d.lib也拷贝到exe所在文件夹(x64/Release)。再一次,如果环境中没有python39_d.lib文件,就把python39.lib复制一份,重命名为python39_d.lib。(在我的测试中,这一步不执行也没问题)

拷贝到:

 步骤四: 在VS2017中,生成并运行项目

得到以下输出,表示设置成功。 

升级--步骤五:创建python工程py_script,C++引入python脚本

        假设python脚本的绝对路径为D:/wzg_projects/C_Python/py_script(具体在哪里无所谓)。创建以下两个python脚本

demo.py

import numpy as np 

def formula1(A,F):
    print(A,F)
    return np.array(A*F)

 hello.py

import demo as d 

def func(a,b):
    num = d.formula1(10,20)
    print("result = {}".format(num))
    print("hello world")

在VS2017中,更改 c_python_test.cpp 脚本的内容:

c_python_test.cpp


#include <iostream>
#include <Python.h>
#include <string>
using namespace std;

int main_()
{
	// 1. 开始python与c++的接口模块,初始化。
	Py_Initialize();//使用python之前,要调用Py_Initailize()函数,进行初始化
	if (!Py_IsInitialized())
	{
		printf("python与c++的接口模块初始化失败");
		return 0;
	}

	// 2. 可行性的基础验证,测试成功后可注释掉
	//PyRun_SimpleString("print('hello world')");
	//PyRun_SimpleString("import numpy as np");

	// 3. 添加python脚本的搜索路径
	PyRun_SimpleString("import sys");
	PyRun_SimpleString("sys.path.append('D:/wzg_projects/C_Python/py_script')");

	// 4. 定义pythonObject类对象,并实例化,前向计算
	PyObject* pModule = NULL;
	PyObject* pFunc = NULL;
	
	// 1)pModule实例化
	pModule = PyImport_ImportModule("hello");//通过python文件名寻找python脚本,文件名不用加后缀,把python脚本编码为c++格式
	if (pModule == NULL)  // 如果找不到文件就报错
	{
		cout << "没找到python脚本:hello.py" << endl;
		return 0;
	}

	// 2) pFunc 实例化
	pFunc = PyObject_GetAttrString(pModule, "func");//从pModule脚本中提取名字为“func”的函数,封装为c++格式的pFunc函数
	if (!pFunc || !PyCallable_Check(pFunc)) {
		cout << "没找到python函数:func" << endl;
		return 0;
	}

	// 3) 把C++变量转变成Python格式
	//    i) 参变量的定义方式1
	//PyObject* pArgs = Py_BuildValue("ii", 25, 6); // 定义函数的参变量。"ii"表示定义两个int类型的变量。还有许多其他格式,可以具体情况具体改变。
	//    ii) 参变量的定义方式2--推荐使用
	PyObject* pArgs = PyTuple_New(2);
	PyTuple_SetItem(pArgs, 0 ,Py_BuildValue("i", 25)); // 把一个int类型的数据“25”放在python tuple的索引为0的位置。
	PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 6)); // 把一个int类型的数据“25”放在python tuple的索引为0的位置。

    // 4) 运行python函数
	PyObject* pReturn = PyObject_CallObject(pFunc, pArgs); // 运行python函数,计算函数的输出结果。把参数args2输入到函数pFunc中,计算输出结果,存储到pRet中。


	// 5. 把python格式的数据转变成c++格式
	int cReturn = 0;
	PyArg_Parse(pReturn, "i", &cReturn);//注意:PyArg_Parse的最后一个参数,必须加上“&”符号。“i”表示转变成int类型的变量。
	cout << "cReturn:" << cReturn << endl;

	// 6. 结束python与c++的接口模块
	Py_Finalize();
	system("pause");
	return 0;
}

        重新生成项目,运行,可以实现对python脚本的调用。具体如何调用,请看上面的代码,注释还是比较详细的。

提示与思考:

  1.  如果python脚本中存在bug,无法运行,或找不到依赖库,c++脚本仍旧可以顺利编译成功,但是在运行时会提示无法找到python文件,比如无法找到上面的“hello.py”
  2. 步骤三中的过程----拷贝Anaconda虚拟环境的根目录下的“DLLs”和“Lib”两个文件夹复制到exe所在文件夹(x64/Release)。没有exe文件夹就先编译生成一个。这一步很重要,否则C++无法找到虚拟环境中的第三方依赖库,比如我们上面安装的numpy库。 这一步不可省略。经试验,把这两个文件夹添加到vs2017的库目录中,也无法解决这个问题。
  3. 在步骤五的c_python_test.cpp脚本中,需要设置python脚本的寻找路径,防止C++找不到python脚本。为了未来的可扩展性、易用性和可移植性,或许这一步可以通过cmake、qt等方式以自动化的方式解决。
  4. 应该编写一个接口函数,用于c++和python相互传递参数,并把这个函数固定下来。
  5. linux环境下,没有vs2017,应该如何设置c++的python依赖库呢?用cmake编译好?

 

参考及进一步学习:

[1] C++调用python方法及环境配置(Windows环境、VS工具)

[2] C++调用Python遇到的问题总结(anaconda的虚拟环境、使用python第三方库,如pytorch、pytorch geometric) [3] C++调用Python(混合编程)函数整理总结

[4] C++调用python脚本 

[5] C/C++ 调用Python 

[6] C++调用python 之 环境配置(VS2015 + anaconda)

[7] C++调用python文件(包含第三方库) 

更多扩展教程:

[1]  图像处理深度学习python代码改写成c++推理

[2] python调用C++中的函数【最简明教程】 

[3] [pybind11]为c++项目写python API接口 - 知乎 

[4] C++和python的代码如何相互调用? - 知乎 

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

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

相关文章

有IP没有域名可以申请证书吗?

一、IP证书是什么&#xff1f; ip证书是用于公网ip地址的SSL证书&#xff0c;与我们通常所讲的SSL证书并无本质上的区别&#xff0c;但由于SSL证书通常颁发给域名&#xff0c;而组织机构需要公共ip地址的SSL证书&#xff0c;这类SSL证书就是我们所说的ip证书。ip证书具有安全、…

数据结构与算法编程题35

用按层次顺序遍历二叉树的方法&#xff0c;统计树中具有度为1的结点数目。 #define _CRT_SECURE_NO_WARNINGS#include <iostream> using namespace std;typedef char ElemType; #define ERROR 0 #define OK 1 #define Maxsize 100 #define STR_SIZE 1024typedef struct B…

软件集成指南

软件集成方法&#xff1a; 1、一次性集成方式 2、增殖式集成方式 2.1、自顶向下的集成方式 2.2、自底向上的集成方式 2.3、混合集成方式

2的幂运算

2的幂 描述 : 给你一个整数 n&#xff0c;请你判断该整数是否是 2 的幂次方。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 如果存在一个整数 x 使得 n 2x &#xff0c;则认为 n 是 2 的幂次方。 题目 : LeetCode 231.2的幂 : 231. 2 的幂 分…

jmeter负载测试如何找到最大并发用户数

在性能测试中&#xff0c;当我们接到项目任务时&#xff0c;很多时候我们是不知道待测接口能支持多少并发用户数的。此时&#xff0c;需要我们先做负载测试&#xff0c;通过逐步加压&#xff0c;来找到最大并发用户数。那么当我们找到一个区间&#xff0c;怎么找到具体的值呢&a…

Large Language Models areVisual Reasoning Coordinators

目录 一、论文速读 1.1 摘要 1.2 论文概要总结 二、论文精度 2.1 论文试图解决什么问题&#xff1f; 2.2 论文中提到的解决方案之关键是什么&#xff1f; 2.3 用于定量评估的数据集是什么&#xff1f;代码有没有开源&#xff1f; 2.4 这篇论文到底有什么贡献&#xff1…

Python-简单模拟斗地主洗牌发牌

额滴名片儿 &#x1f388; 博主&#xff1a;一只程序猿子 &#x1f388; 博客主页&#xff1a;一只程序猿子 博客主页 &#x1f388; 个人介绍&#xff1a;爱好(bushi)编程&#xff01; &#x1f388; 创作不易&#xff1a;如喜欢麻烦您点个&#x1f44d;或者点个⭐&#xff01…

组合(回溯算法)

77. 组合 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 样例输入 示例 1&#xff1a; 输入&#xff1a;n 4, k 2 输出&#xff1a; [[2,4],[3,4],[2,3],…

Linux基本指令(中篇)

目录 8.cp指令&#xff08;重要&#xff09; 9.mv指令&#xff08;重要&#xff09;&#xff1a; 10.cat指令&#xff08;适合查看小文件内容&#xff09; 11.more指令&#xff08;适合查看大文件内容&#xff09; 12.less指令&#xff08;重要&#xff09; 13.head指令和…

开源众筹平台系统源码/高仿某滴筹平台源码/PHP源码/互助众筹系统网站源码

源码简介&#xff1a; 开源众筹平台系统源码&#xff0c;它是高仿某滴筹平台源码&#xff0c;互助众筹系统网站源码&#xff0c;作为PHP源码&#xff0c;很实用。 高仿水滴筹源码,全开源uniappfastadmin开发 这套是uniapp 开发源码,非常人性化,可以随意二开 源码链接&#xf…

上门服务系统|东郊到家软件提供高效服务的科技支柱

预约上门服务系统的崛起改变了传统服务行业的格局。用户不再需要亲自前往实体店面&#xff0c;而是通过几次点击就能享受到各类服务。这背后离不开预约上门服务系统的智能化和高效性&#xff0c;而源码正是这个系统的灵魂所在。下面小编就给大家介绍下上门服务系统开发优势。 1…

智能优化算法应用:基于风驱动算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于风驱动算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于风驱动算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.风驱动算法4.实验参数设定5.算法结果6.参考文献7.…

[c++]—string类___深度学习string标准库成员函数与非成员函数

要相信别人能做出来自己一定可以做出来&#xff0c;只不过是时间没到而已 目录 &#x1f6a9;string类对象capacity操作 &#x1f4bb;reserve()保留 &#x1f4bb;resize() &#x1f6a9;string类对象元素访问操作 &#x1f4bb;operator[]和at() &#x1f4bb;operator…

EasyExcel如何读取全部Sheet页数据方法

一、需求描述 Excel表格里面大约有20个sheet页&#xff0c;每个sheet页65535条数据&#xff0c;需要读取全部数据&#xff0c;并导入至数据库。 找了好多种方式&#xff0c;EasyExcel比较符合&#xff0c;下面看代码。 二、实现方式 采用EasyExcel框架的doReadAll()方法 1、…

Ranger安装和使用

Ranger部署 1.准备 1.1 编译 Ranger编译&#xff08;已经编译过的话&#xff0c;直接看1.2&#xff09; 1.1.1 准备到Ranger官网下载ranger的源码&#xff1a;http://ranger.apache.org/download.html 1.1.2 Ranger编译的过程实在非虚拟机环境下完成的&#xff0c;下载好r…

中职组网络安全-PYsystem003.img(环境+解析)

​ web安全渗透 1.通过URL访问http://靶机IP/1&#xff0c;对该页面进行渗透测试&#xff0c;将完成后返回的结果内容作为flag值提交&#xff1b; 访问该网页后发现F12被禁用&#xff0c;使用ctrlshifti查看 ctrlshifti 等效于 F12 flag{fc35fdc70d5fc69d269883a822c7a53e} …

应用分发平台怎么看数据

地图统计 ●所有版本应用内测包体总统计地图方便更容易看到地区和用户的聚集 折线统计 ●所有版本应用内测包体总统计方便分析每天的测试状态&#xff0c;方便调整策略 数字统计 ●所有版本应用内测包体总统计数字看到直观的数据

基于社区电商的Redis缓存架构-用户分享内容的分页列表缓存延迟构建以及异步通知缓存重建

分页列表缓存的延迟构建 首先&#xff0c;先来讲一下业务场景&#xff0c;用户会在 APP 中去分享内容&#xff0c;那么假如用户分享的是美食菜谱内容&#xff0c;在用户分享之后&#xff0c;先将这个美食菜谱的内容作为 k-v 进行缓存&#xff0c;但是呢&#xff0c;其实对于用…

如何计算数据泄露的成本

现在&#xff0c;几乎所有类型的组织每天都在发生企业 IT 网络遭到破坏的情况。它们是任何合规官员最担心的问题&#xff0c;并且找出更好的方法来防止它们或从中恢复是合规官员永远不会远离的想法。 但数据泄露的实际成本是多少&#xff1f;该数字从何而来&#xff1f;当您获…

无人机助力电力设备螺母缺销智能检测识别,python基于YOLOv7开发构建电力设备螺母缺销高分辨率图像小目标检测系统

传统作业场景下电力设备的运维和维护都是人工来完成的&#xff0c;随着现代技术科技手段的不断发展&#xff0c;基于无人机航拍飞行的自动智能化电力设备问题检测成为了一种可行的手段&#xff0c;本文的核心内容就是基于YOLOv7来开发构建电力设备螺母缺销检测识别系统&#xf…