从C++调用 Python 并访问通过 Anaconda 安装的软件包

Calling Python from C++ and accessing packages installed via Anaconda

本文关键字:Anaconda 安装 软件包 访问 C++ 调用 Python      更新时间:2023-10-16

我开发了一些Python代码,从我的基本Anaconda环境中对热设备进行建模。此代码使用某些包,例如numpy,这些包已安装到该环境中。

我想将此代码与同一工作站(MS Windows 10 OS(上的商业热系统建模程序连接。程序/Python 接口通过编译成 DLL 的一些C++代码进行处理。 简化的代码段如下所示:

#include <Python.h>
scriptName = "PyScript"
functionName = "InterfaceFunction"
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("import os");
PyRun_SimpleString("sys.path.append(os.getcwd())");
pName = PyUnicode_DecodeFSDefault(scriptName.c_str());
pModule = PyImport_Import(pName); // Here's where things go bad.
pFunc = PyObject_GetAttrString(pModule, functionName.c_str());
pValue = PyObject_CallObject(pFunc, NULL);

该接口用于在仅使用内置 Python 功能的简单 Python 脚本中调用函数。但是,我想运行的实际代码需要为安装到基本 Anaconda 环境中的上述几个包提供一些import语句。尝试导入其中任何一个都会导致加载脚本时调用失败。 具体来说,该语句pModule = PyImport_Import(pName)导致pModule == 'NULL'为真。

我已经在PYTHONPATH系统环境变量中包含我的关键 Anaconda 环境目录,包括:

C:ProgramDataAnaconda3
C:ProgramDataAnaconda3DLLs
C:ProgramDataAnaconda3Lib
C:ProgramDataAnaconda3DLibsite-packages

我还尝试在执行activate.bat base命令后从CMD.exe窗口启动调用程序,但包导入仍然导致失败。

有没有办法在PyImport_Import()调用之前为C++代码中的调用过程激活我的 Anaconda 基础环境,以使模块正确导入?还是我只是需要放弃 Anaconda 的环境并在不使用环境的情况下重新安装 python 和所有需要的模块?

如果您尝试使用基本环境在 conda 中运行 python 脚本,请尝试以下操作,将 -V 替换为您的 python 脚本:

conda run -n base python -V

蟒蛇 3.7.6

在C++中,如果你能够运行一个 Python 脚本,你可以试试这个:

import subprocess
subprocess.run('c:\Users\iowahawk89\miniconda3\condabin\conda.bat activate base && "c:\Users\iowahawk89\miniconda3\Scripts\conda.exe" "list" && conda deactivate', shell=True)
subprocess.run('c:\Users\iowahawk89\miniconda3\Scripts\conda.exe run -n base python hello.py', shell=True)

或者如果你想直接在解释器中运行 Python,你可以试试这个:

subprocess.run('c:\Users\iowahawk89\miniconda3\Scripts\conda.exe run -n base python -V', shell=True)

其他想法:

subprocess.run('c:\Users\iowahawk89\miniconda3\Scripts\conda.exe run -n base python -V', shell=True)
subprocess.run('c:\Users\iowahawk89\miniconda3\Scripts\conda.exe run -n base python hello.py', shell=True)

保存输出以供以后使用

output = subprocess.check_output(['c:\Users\iowahawk89\miniconda3\Scripts\conda.exe', 'list', '-n', 'base'])
print('Have %d bytes in output' % len(output))
print(output)
output = subprocess.check_output(['c:\Users\iowahawk89\miniconda3\condabin\conda.bat', 'activate', 'base'], shell=True)

在所有情况下,我都能从我的 conda 环境中看到正确的 python 版本。