本文介绍: 这一点对大家来说应该简单,简单介绍一下,不做过多解释

步骤一:在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&gt;
#include <string&gt;
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的项目属性&gt;>配置属性>>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.libpython39.libpython39_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", &amp;cReturn);//注意:PyArg_Parse的最后一个参数,必须加上“&amp;”符号。“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脚本。为了未来的可扩展性、易用性和可移植性,或许这一步可以通过cmakeqt方式自动化方式解决
  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的代码如何相互调用? – 知乎 

原文地址:https://blog.csdn.net/Strive_For_Future/article/details/134723738

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_24124.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注