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

2023-12-01 12:04

本文主要是介绍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/441082

相关文章

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

Python版本信息获取方法详解与实战

《Python版本信息获取方法详解与实战》在Python开发中,获取Python版本号是调试、兼容性检查和版本控制的重要基础操作,本文详细介绍了如何使用sys和platform模块获取Python的主... 目录1. python版本号获取基础2. 使用sys模块获取版本信息2.1 sys模块概述2.1.1

一文详解Python如何开发游戏

《一文详解Python如何开发游戏》Python是一种非常流行的编程语言,也可以用来开发游戏模组,:本文主要介绍Python如何开发游戏的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、python简介二、Python 开发 2D 游戏的优劣势优势缺点三、Python 开发 3D

Python函数作用域与闭包举例深度解析

《Python函数作用域与闭包举例深度解析》Python函数的作用域规则和闭包是编程中的关键概念,它们决定了变量的访问和生命周期,:本文主要介绍Python函数作用域与闭包的相关资料,文中通过代码... 目录1. 基础作用域访问示例1:访问全局变量示例2:访问外层函数变量2. 闭包基础示例3:简单闭包示例4

Python实现字典转字符串的五种方法

《Python实现字典转字符串的五种方法》本文介绍了在Python中如何将字典数据结构转换为字符串格式的多种方法,首先可以通过内置的str()函数进行简单转换;其次利用ison.dumps()函数能够... 目录1、使用json模块的dumps方法:2、使用str方法:3、使用循环和字符串拼接:4、使用字符

Python版本与package版本兼容性检查方法总结

《Python版本与package版本兼容性检查方法总结》:本文主要介绍Python版本与package版本兼容性检查方法的相关资料,文中提供四种检查方法,分别是pip查询、conda管理、PyP... 目录引言为什么会出现兼容性问题方法一:用 pip 官方命令查询可用版本方法二:conda 管理包环境方法

基于Python开发Windows自动更新控制工具

《基于Python开发Windows自动更新控制工具》在当今数字化时代,操作系统更新已成为计算机维护的重要组成部分,本文介绍一款基于Python和PyQt5的Windows自动更新控制工具,有需要的可... 目录设计原理与技术实现系统架构概述数学建模工具界面完整代码实现技术深度分析多层级控制理论服务层控制注

pycharm跑python项目易出错的问题总结

《pycharm跑python项目易出错的问题总结》:本文主要介绍pycharm跑python项目易出错问题的相关资料,当你在PyCharm中运行Python程序时遇到报错,可以按照以下步骤进行排... 1. 一定不要在pycharm终端里面创建环境安装别人的项目子模块等,有可能出现的问题就是你不报错都安装

Python打包成exe常用的四种方法小结

《Python打包成exe常用的四种方法小结》本文主要介绍了Python打包成exe常用的四种方法,包括PyInstaller、cx_Freeze、Py2exe、Nuitka,文中通过示例代码介绍的非... 目录一.PyInstaller11.安装:2. PyInstaller常用参数下面是pyinstal