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

2023-12-01 15:01

本文主要是介绍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的代码如何相互调用? - 知乎 

这篇关于C++调用python: VS2017 + Anaconda + pypi第三方库的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/441622

相关文章

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学