【问题标题】:Calling Python from C++ and accessing packages installed via Anaconda从 C++ 调用 Python 并访问通过 Anaconda 安装的包
【发布时间】:2020-06-23 02:28:11
【问题描述】:

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

我想将此代码与同一工作站(MS Windows 10 操作系统)上的商业热系统建模程序接口。程序/Python 接口是通过一些编译成 DLL 的 C++ 代码来处理的。一个简化的 sn-p 看起来像:

#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 脚本中调用函数。但是,我想要运行的实际代码需要一些 import 语句,用于安装到基本 Anaconda 环境中的上述几个包。加载脚本时尝试导入其中任何一个都会导致调用失败。具体来说,pModule = PyImport_Import(pName) 语句导致 pModule == 'NULL' 为真。

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

C:\ProgramData\Anaconda3
C:\ProgramData\Anaconda3\DLLs
C:\ProgramData\Anaconda3\Lib
C:\ProgramData\Anaconda3D\Lib\site-packages

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

PyImport_Import() 调用之前,有什么方法可以在 C++ 代码中为调用进程激活我的 Anaconda 基础环境,以使模块正确导入?还是我只是坚持需要删除 Anaconda 的环境并在不使用环境的情况下重新安装 python 和所有需要的模块?

【问题讨论】:

    标签: python c++ anaconda conda environment


    【解决方案1】:

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

    conda run -n base python -V
    

    Python 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 版本。

    【讨论】:

    • 感谢 Donald,但不幸的是,我不是从命令行调用脚本,而是使用“Python.h”标头中的 Python API 从编译的 C++ 函数中调用脚本。在 Python 调用之前,我确实尝试通过源代码中的std::system("activate.bat base"); 运行环境配置命令,但该命令似乎没有影响调用程序。
    • 我在上面添加了一些选项,希望其中一个可以解决您的特定问题。
    猜你喜欢
    • 1970-01-01
    • 2018-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多