vs2019调用python程序

文章介绍了如何在C++环境中配置Python库,通过VS2019调用Python代码执行PID算法。首先,配置C++项目以包含Python环境,接着编写PythonPID类,然后在C++中导入Python模块,实例化类并调用其方法。文章还展示了C++主函数如何与Python交互并打印结果。
摘要由CSDN通过智能技术生成

因为最近项目需要,需要在c++程序中调用python代码进行部分数学预处理,因此在此记录python调用c++的过程,以防自己遗忘,并供大家参考。

测试环境

vs版本:VS2019
Anaconda版本:4.10.3
anaconda版本可以通过如下命令查看:

conda info

在这里插入图片描述
使用的python版本为anaconda默认版本:3.6

1.c++环境配置

在调用python之前,我们首先需要在c++项目中配置python依赖库,选择配置的python解释器位于Anaconda下的envs里的torch环境中。
先创建一个c++空项目:

在这里插入图片描述
然后在项目属性里分别添加include目录和libs库:
在这里插入图片描述
最后添加链接器python37.lib:
在这里插入图片描述

至此,c++端环境即配置完毕。

2.python代码编写

接下来,我们需要有一个python代码:
import numpy as np
# import matplotlib.pyplot as plt

class CPID():
    def __init__(self):
        self.I = 0
        self.error_last = 0

    def init(self, target, position, KP, KI, KD, KI_limit=None, KI_band=None, Out_limit=None):
        self.target = target
        self.position = position
        self.KP = KP
        self.KD = KD
        self.KI = KI
        self.KI_limit = KI_limit
        self.KI_band = KI_band
        self.Out_limit = Out_limit

    def calculate(self):
        error = self.target - self.position

        if self.KI_band != None:
            if self.I > self.KI_band:
                self.I = 0
            else:
                if self.KI_limit != None:
                        if self.I > self.KI_limit:
                            self.I = self.KI_limit
                        else:
                            self.I = self.I + self.KI * error
                else:
                    self.I = self.I + self.KI * error
        else:
            self.I = self.I + self.KI * error

        out = self.KP*error + self.I + self.KD*(error-self.error_last)
        if self.Out_limit != None:
            if out > self.Out_limit:
                out = self.Out_limit
        
        self.position = self.position + out
        self.error_last = error

        # 更新目标
        self.target = 500 + np.random.randint(-50, 50)

        return self.target, self.position


这是一个简易PID算法,供c++端调用。

3.c++端代码编写

c++端代码如下:
#include <Python.h>
#include <iostream>

//c++调用python
int main()
{
	//设置python解释器的路径,避免主机内存在多个python环境导致程序运行错误
	Py_SetPythonHome((wchar_t*)L"E:\\anaconda\\envs\\torch");
	//进行初始化
	Py_Initialize();

	//导入python文件路径
	PyRun_SimpleString("import sys");
	PyRun_SimpleString("sys.path.append('D://Python_HJ//PID')");  
	//导入要调用的py文件
	PyObject* pModule = PyImport_ImportModule("pid");
	//加载文件中的函数名、类名
	PyObject* pDict = PyModule_GetDict(pModule);
	//根据类名获得该类
	PyObject* pClass = PyDict_GetItemString(pDict, "CPID");
	//根据函数名获取该函数
	/*PyObject* pFunc = PyObject_GetAttrString(pDict, "init");
	PyObject* pFunc1 = PyObject_GetAttrString(pDict,"update");*/
	//得到类的构造函数
	PyObject* pConstruct = PyInstanceMethod_New(pClass);
	//类的实例化
	PyObject* pInstance = PyObject_CallObject(pConstruct, NULL);
	
	float res1 = 0;
	float res2 = 0;

	for (int i = 0; i < 100; ++i) {
		//调用python对象的方法并赋值
		PyObject_CallMethod(pInstance, "init", "iifff", 500, 0, 0.5, 0.01, 0.25);
		PyObject* RES = PyObject_CallMethod(pInstance, "calculate", NULL);
		//将返回结果转换成C++类型
		//PyArg_Parse(RES, "f", &res);  用于处理单数据输出
		PyArg_ParseTuple(RES, "ff", &res1, &res2);
		
		std::cout << "target:" << res1 << "\t";
		std::cout << "position:" << res2 << std::endl;
	}

	return 0;
	system("pause");
}
运行结果如下:

在这里插入图片描述
至此,成功在c++程序中完成对python程序的调用。
这里仍有几个点需要注意:
1.本项目用的是ReleaseX64,若要使用DebugX64版,需要提供python37_d.lib库,若要使用X86版本,则需下载32位的python版本;
2.出现找不到dll文件的情况,需要将python37.dll文件拷贝到c://windows//System32中。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值