首页 > 系统相关 >C++调用python方法及环境配置(Windows环境、VS工具)

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

时间:2023-01-18 11:44:56浏览次数:60  
标签:BuildValue python Py C++ Windows VS numpy

c++和python使用混合编程,有四种方式来实现:

  • (1)C++调用python
  • (2)直接调用python文件并执行
  • (3)3.使用Cpython:这是一个第三方库,可以将python代码直接变成c代码
  • (4)使用pybind11库(建议),网址:pybind/pybind1

在这里描述VS写C++中调用python(方法一)的流程。

1.c++在VS中调用python的配置

其中python是一种非常强大的胶水语言,可以灵活的嵌入到c++和java等主流语言中。

1.1安装python

在python的官方网站Welcome to Python.org下载64位的安装包,在安装过程点击设置环境变量(很重要)。在目前的一些版本中,安装python是同时安装了pip的。

安装完python后,打开cmd,在其中输入

pip3 install numpy
pip3 install matplotlib

第一句用来安装numpy库,第二句用来安装绘图matplotlib库。当python为3.0以上版本,采用pip3安装;若为python2.7,则采用pip安装。

1.2在VS中设置调用python

若下载的python版本为64位,则在VS中将Debug修改为X64;若下载的python版本为32位,则在VS中将Debug修改为X86。

然后在VS的项目属性>>配置属性>>C/C++>>添加包含目录中,将Python的根目录下的include文件夹添加进来。(Python的根目录:如果按照默认位置安装,目录在C:\Users\Administrator\AppData\Local\Programs\Python\的路径下)

然后在VS的项目属性>>配置属性>>链接器>>附件库目录中,将Python的根目录下的libs文件夹添加进来。

1.3测试编译运行

在VS中新建一个文件.cpp的源文件,然后复制如下代码:

#include<Python.h>
int main()
{
	Py_Initialize();   

	PyRun_SimpleString("print ('hello')");

	PyRun_SimpleString("import numpy as np");

	Py_Finalize();

	system("pause");
	return 0;

若不报错,同时打印了hello则表明完成。

2.C++调用python

python作为一种强力的胶水语言,可以在其他语言中使用,特别是目前深度学习的快速发展,使用python搭建模型,训练是非常高效的。而在部署过程中使用C++时就出现问题了。但是如何解决部署中的问题,并不是本文的主题。

2.1 基础

python的C、C++外部扩展官方教程,可以在网页的上部选择python的版本:

https://docs.python.org/3.6/extending/embedding.html​docs.python.org/3.6/extending/embedding.html

python提供了一套C的API库,是的开发者能够很方便的从C、C++的程序中调用python中的各个功能模块。

此环境配置是在Windows的环境下,Linux不适用,但是方法思想一致:首先设置python的头文件,然后设置python的库文件。

首先按照1中搭建出c++和python混合编程的环境。

2.1.1 初始化Python解释器

例子:

#include<Python.h>

int main(){
    
    Py_Initialize();  //必要,初始化python解释器
    Py_Initialize();
	if (!Py_IsInitialized()) {
		std::system("pause");
		return -99;
	}//查看是否成功初始化
    
    /*  需要执行的python语句  */
    
    PyRun_SimpleString("import sys");
    PyRun_SimpleString(print('hello!'));
    
    /*  结束需要执行的python  */
    
    Py_Finalize(); //释放Python资源
    
    return 0;
}

2.1.2 调用Python函数(c++不向python传参)

假设你有一个名叫plot3dfun.py的python文件,你想调用其中的名叫print_test的函数。

plot3dfun.py文件为:

import numpy as np
def print_test1():
    print("hello, this is python")

首先,你要将plot3dfun.py文件放到你VS项目的固定位置上:若你使用的是debug(X64)模式,则plot3dfun.py放到你的Project目录>>x64>>Debug目录下;若你使用的是Release目录,则plot3dfun.py放到你的Project目录>>x64>>Release目录下。

C++程序为:

#include<iostream>
#include<Python.h>

int main(){
    Py_Initialize(); //初始化python解释器
	if (!Py_IsInitialized()) {
		std::system("pause");
		return -99;
	} //查看python解释器是否成功初始化
	
	PyObject *pName, *pModule, *pDict, *pFunc; //定义python对象
	
	pName = PyUnicode_FromString("plot3dfun");
	pModule = PyImport_Import(pName); //载入plot3dfun的模块
	if (!pModule) {
		cout << "Can't find plot3dfun.py" << endl;
		std::system("pause");
		return -98;
	} //查看是否载入了模块
	
	PyObject* pFunc = PyObject_GetAttrString(pModule, "print_test1");
	if (!pFunc || !PyCallable_Check(pFunc)) {
		cout << "error: pFunc" << endl;
		std::system("pause");
		return -96;
	}
	
	//调用print_test函数
	PyObject_CallObject(pFunc, NULL );
	
	//销毁python相关
	Py_DECREF(pName);
	Py_DECREF(pModule);
	Py_Finalize();

运行程序,可以看到程序能够输出hello, this is python。

2.1.3 调用Python函数(c++向python传参)

在很多时候,c++需要向python传参,让python执行相关操作。python提供了各种数据类型用于和C中的数据类型进行转换,具体的思想是相同的,这里只举几个例子。

字符串传参

假设你有一个名叫plot3dfun.py的python文件,你想调用其中的名叫print_test的函数。

plot3dfun.py文件为:

import numpy as np
def print_test1():
    print("hello, this is python")
def print_test2(string_in):
    print(string_in)

首先,你要将plot3dfun.py文件放到你VS项目的固定位置上:若你使用的是debug(X64)模式,则plot3dfun.py放到你的Project目录>>x64>>Debug目录下;若你使用的是Release目录,则plot3dfun.py放到你的Project目录>>x64>>Release目录下。

c++文件为:

#include<iostream>
#include<Python.h>

int main(){
    Py_Initialize(); //初始化python解释器
	if (!Py_IsInitialized()) {
		std::system("pause");
		return -99;
	} //查看python解释器是否成功初始化
	
	PyObject *pName, *pModule, *pDict, *pFunc, *pArgs; //定义python对象
	
	pName = PyUnicode_FromString("plot3dfun");
	pModule = PyImport_Import(pName); //载入plot3dfun的模块
	if (!pModule) {
		cout << "Can't find plot3dfun.py" << endl;
		std::system("pause");
		return -98;
	} //查看是否载入了模块
	
	PyObject* pFunc = PyObject_GetAttrString(pModule, "print_test1");
	if (!pFunc || !PyCallable_Check(pFunc)) {
		cout << "error: pFunc" << endl;
		std::system("pause");
		return -96;
	}
	
	//调用print_test2函数
	pArgs = PyTuple_New(1);//创建一个元组,长度为1。
	PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", "this is a test"));//将pArgs的第一(0)个变量设置为字符串(s) “this is a test”
	PyObject_CallObject(pFunc, pArgs);
	
	//销毁python相关
	Py_DECREF(pName);
	Py_DECREF(pModule);
	Py_Finalize();
}

上述程序中,PyObject* PyTuple_New(Py_ssize_t len)返回函数所创建的元组,所创建元组的长度为len。

左边为C++中的输入形式,右边为对应的python中的高级数据结构形式。

#define PY_SSIZE_T_CLEAN  /* Make "s#" use Py_ssize_t rather than int. */
#include <Python.h>

Py_BuildValue("")                        None
Py_BuildValue("i", 123)                  123
Py_BuildValue("iii", 123, 456, 789)      (123, 456, 789)
Py_BuildValue("s", "hello")              'hello'
Py_BuildValue("y", "hello")              b'hello'
Py_BuildValue("ss", "hello", "world")    ('hello', 'world')
Py_BuildValue("s#", "hello", 4)          'hell'
Py_BuildValue("y#", "hello", 4)          b'hell'
Py_BuildValue("()")                      ()
Py_BuildValue("(i)", 123)                (123,)
Py_BuildValue("(ii)", 123, 456)          (123, 456)
Py_BuildValue("(i,i)", 123, 456)         (123, 456)
Py_BuildValue("[i,i]", 123, 456)         [123, 456]
Py_BuildValue("{s,s}", "abc", "def")     {'abc', 'def'}
Py_BuildValue("{s:i,s:i}",
              "abc", 123, "def", 456)    {'abc': 123, 'def': 456}
Py_BuildValue("((ii)(ii)) (ii)",
              1, 2, 3, 4, 5, 6)          (((1, 2), (3, 4)), (5, 6))

上述的一些更详细的操作说明可以查看官方的文档,或者一下的描述:

C/C++调用Python[OpenCV与Numpy]_ziweipolaris的博客-CSDN博客_c++调用numpy

码农自来也:C++调用python脚本

2.2 c++调用numpy和Opencv

首先要查看python的版本是release版本还是debug版本,一般安装的python都是Release版本。VS编写C++时,改为Release模式,这要与python的版本一致,否则会报错:

无法解析的外部符号 __imp___Py_RefTotal

如果将版本调整为相同的Release,则不会存在此问题。

调用numpy首先要将numpy的相关目录包含到VS中,在项目》项目属性页》C/C++》附加包含目录 中添加:

C:\Users\Administrator\AppData\Local\Programs\Python\Python36\Lib\site-packages\numpy\core\include

在调用numpy之前,要初始化一下,载入numpy的各个功能模块,也就是要添加代码并调用:

size_t numpy_init() {
	import_array();
}

给python发送numpy数组代码:

npy_intp Dims[] = { JointType_Count, 3 };
cout << "push data to python numpy!" << endl;
PyObject *PyyArray = PyArray_SimpleNewFromData(2, Dims, NPY_FLOAT, (void *)toPython_XYZ);
PyObject *ArgArray = PyTuple_New(1);
PyTuple_SetItem(ArgArray, 0, PyyArray); //同样定义大小与Python函数参数个数一致的PyTuple对象															///*PyObject *pFuncFive = PyDict_GetItemString(pDict, "PassArrayFromCToPython");*/
PyObject_CallObject(pFunc, ArgArray);

更多的Numpy C API例子可以查看:

How to extend NumPy​numpy.org/devdocs/user/c-info.how-to-extend.html

2.3 c++动态画图(matplotlib)

想造轮子的刘大胆:C++中使用matplotlib绘图

ref:C++调用python方法及环境配置(Windows环境、VS工具) - 知乎 (zhihu.com)

标签:BuildValue,python,Py,C++,Windows,VS,numpy
From: https://www.cnblogs.com/lidabo/p/17059485.html

相关文章

  • Python判断值是否在列表中进阶用法
    初级使用方式一般会这样写domain=["naihe.me","abc.com","123.cn","efg.xyz"]foriindomain:ifi=="naihe.me":print(i=="naihe.me")......
  • 使用 Python Paramiko 的嵌套 SSH
    ssh嵌套:https://stackoverflow.com/questions/35304525/nested-ssh-using-python-paramiko......
  • Python使用pyppeteer搭建网页截图api
    因为跨语言需要,打算把pyppeteer、图片压缩、awsS3封装成一个api来调用。首先自然是要安装依赖pip3installpillowboto3pyppeteer运行一次脚本,pyppeteer会自动下载最......
  • python re 正则表达式
    1.匹配两个数字importreres=re.search(r"[0-9]{2}","sadfsda35C")#正则表达式为[0-9]{2}#匹配的字符串为sadfsda35Cprint(res)  2.匹配两个数字(另一种......
  • windows关机与重启bat脚本
    电脑设置每天定时关机1、同时按下Windows徽标键+R键,调出“运行”框;在“运行”框中输入命令control,并点击“确定”,即可打开控制面板2、打开控制面板后,右上角可以切换不同......
  • windows根据端口号查询pid 然后杀掉进程
    新建一个test.bat文件copy下面内容,并根据实际情况修改端口@echooff&color3d&setlocalenabledelayedexpansion::ipconfig>ip.txtnetstat-aon|findstr6666>p......
  • linux jenkins添加windows节点
    1.添加jenkinsnode2.下载jar包上面提供两种方法,第一种下载文件,默认java去启动和运行程序。第二个,你可以拷贝这个命令,放到一个记事本文件,然后保存为bat文件,双击bat文件也......
  • Windows安装使用npm(Nodejs)
    1.下载Nodejs​​​https://nodejs.org/en​​2.傻瓜式的安装,路径可以自己更改3.配置NODE_PATH环境变量(安装自动配置路径)4.安装好后,对应的各个文件的作用:检查是否正常先......
  • 在windows系统中设置JVM(Java虚拟机)的内存
    虚拟机内存的大小除了在web容器中设置,我们还可以通过系统环境变量来设置,下面看看设置步骤:1.打开windows系统环境变量,在系统变量中,新建变量JAVA_OPTS,值设置为-Xms1024M-Xm......
  • Windows GIT SSH 免密教程
    1.安装git客户端下载地址:https://github.com/git-for-windows/git/releases/download/v2.23.0.windows.1/Git-2.23.0-64-bit.exe2.安装好后,在桌面右键出现GitGUIhere和......