C++ 调用Python脚本及其第三方库

您所在的位置:网站首页 ue4调用第三方库 C++ 调用Python脚本及其第三方库

C++ 调用Python脚本及其第三方库

2023-06-28 08:50| 来源: 网络整理| 查看: 265

C++ 调用Python脚本及其第三方库 〇、项目说明一、添加环境变量1. PYTHONHOME系统环境变量代码临时变量 2. PYTHONPATH系统环境变量临时环境变量 3. base环境添加到Path 二、 新建VS工程添加新属性表包含目录库目录依赖项 三、 C++调用Python1. 执行简单python语句2. 调用Python脚本中的函数3. 调用整个python脚本4. C++调用python打包的exe 四、 其他const char* 转wchar_t *各类报错一些参考

〇、项目说明

目标是用C++调用Python脚本,该脚本中可能包含各种第三方库,需要使用对应conda环境下的Python解释器。以下将由简单到复杂展示如何使用C++调用Anaconda下的python及其第三方库(以Anaconda 的base环境为例)。

一、添加环境变量

以下PYTHONHOME和PYTHONPATH如果使用系统环境变量方式添加,会影响其他虚拟环境下python的使用,如果需要经常切换虚拟环境或不想反复改动系统环境变量,建议使用代码临时变量的方式添加。

1. PYTHONHOME 系统环境变量 N: PYTHONHOME V: D:\ProgramData\Anaconda3

在这里插入图片描述

代码临时变量 #include // 设置 PYTHONHOME 环境变量 const wchar_t* PYTHONHOME_N = L"PYTHONHOME"; const wchar_t* PYTHONHOME_V = L"D:\\ProgramData\\Anaconda3"; if (!SetEnvironmentVariable(PYTHONHOME_N ,PYTHONHOME_V )) { std::cerr Py_Initialize(); //初始化 PyRun_SimpleString("print('Hello python, i am cpp.')"); Py_Finalize(); //释放 }

执行,成功调用Python解释器进行文本输出。 在这里插入图片描述

2. 调用Python脚本中的函数

在代码中使用临时环境变量,新建一个usingpython_02.cpp。接下来将调用octree_utils.py里的show_octree()函数:

import numpy as np import open3d as o3d def show_octree(pts_path,max_depth=5): """通过点云求open3d的体素集""" pts = np.loadtxt(pts_path, delimiter=" ") # 生成点云数据 pcd = o3d.geometry.PointCloud() pcd.points = o3d.utility.Vector3dVector(pts[:, :3]) # 加入颜色信息 if (len(pts[0, :]) > 5): color = pts[:, 3:6] / 255.0 pcd.colors = o3d.utility.Vector3dVector(color) # 将颜色值归一化到[0, 1] octree = o3d.geometry.Octree(max_depth) octree.convert_from_point_cloud(pcd) o3d.visualization.draw_geometries([octree]) return 1

C++代码:

#include "Python.h" #include #include #include using namespace std; int main() { // 设置 PYTHONHOME 环境变量 const wchar_t* PYTHONHOME_N = L"PYTHONHOME"; const wchar_t* PYTHONHOME_V = L"D:\\ProgramData\\Anaconda3"; if (!SetEnvironmentVariableW(PYTHONHOME_N ,PYTHONHOME_V )) { std::cerr cout cout // 设置 PYTHONHOME 环境变量 const wchar_t* PYTHONHOME_N = L"PYTHONHOME"; const wchar_t* PYTHONHOME_V = L"D:\\ProgramData\\Anaconda3"; if (!SetEnvironmentVariableW(PYTHONHOME_N ,PYTHONHOME_V )) { std::cerr return -1; } Py_Finalize(); return 0; }

测试成功。 在这里插入图片描述

4. C++调用python打包的exe

这种方法跟调用其他exe一样,在这里暂不展开,放一种常用方法:

#include ShellExecute(NULL,L"open",L"./test.exe",NULL,NULL,SW_SHOW); 四、 其他 const char* 转wchar_t *

由于C++调用Python时很多API的参数类型为wchar_t*,所以我让chatGPT写了一个const char* 转wchar_t *的函数。

#include #include #include #include using namespace std; wchar_t* ConvertToWideString(const char* str) { // 获取所需的宽字符长度 size_t length = mbstowcs(nullptr, str, 0); if (length == static_cast(-1)) { // 错误处理 return nullptr; } // 分配足够的内存来存储宽字符 wchar_t* wideStr = new wchar_t[length + 1]; // 执行转换 if (mbstowcs(wideStr, str, length + 1) == static_cast(-1)) { // 错误处理 delete[] wideStr; return nullptr; } return wideStr; } 各类报错

对遇到部分报错记录了一下,基本上按以上方法设置完成后都可以避免。

Fatal Python error… Python path configuration: PYTHONHOME = (not set) PYTHONPATH = (not set) program name = 'python' isolated = 0 environment = 1 user site = 1 import site = 1 sys._base_executable = 'D:\\Project\\CPP_Project\\UsingPython\\x64\\Release\\UsingPython.exe' sys.base_prefix = 'D:\\ProgramData\\Anaconda3' sys.base_exec_prefix = 'D:\\ProgramData\\Anaconda3' sys.platlibdir = 'lib' sys.executable = 'D:\\Project\\CPP_Project\\UsingPython\\x64\\Release\\UsingPython.exe' sys.prefix = 'D:\\ProgramData\\Anaconda3' sys.exec_prefix = 'D:\\ProgramData\\Anaconda3' sys.path = [ 'D:\\ProgramData\\Anaconda3\\python39.zip', '.\\DLLs', '.\\lib', 'D:\\Project\\CPP_Project\\UsingPython\\x64\\Release', ] Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding Python runtime state: core initialized ModuleNotFoundError: No module named 'encodings'

解决方案 见以上PYTHONHOME及PYTHONPATH环境变量设置,建议使用代码临时变量。

UserWarning: mkl-service package failed to import… D:\ProgramData\Anaconda3\Lib\site-packages\numpy\__init__.py:148: UserWarning: mkl-service package failed to import, therefore Intel(R) MKL initialization ensuring its correct out-of-the box operation under condition when Gnu OpenMP had already been loaded by Python process is not assured. Please install mkl-service package, see http://github.com/IntelPython/mkl-service from . import _distributor_init

解决方案 见以上base环境添加到Path

Traceback … Traceback (most recent call last): File "", line 1, in NameError: name 'execfile' is not defined

解决方案 这个其实是python3删除了execfile方法,改用exec方法,但这个方法需要先把代码读下来再执行,所以我在上面调用整个python脚本使用了另一种os.system()方法。

一些参考

参考1、参考2、参考3、参考4



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3