【问题标题】:Keep process running while program continues C++在程序继续 C++ 时保持进程运行
【发布时间】:2019-12-04 08:32:50
【问题描述】:

我希望能够通过 C++ 调用 python 脚本中的函数。该函数会将一些文本打印到标准输出。

但是,python 脚本需要大约 1 分钟才能将全局变量加载到内存中,所以我想在交互模式下保持进程处于活动状态,这样我就可以简单地再次调用函数而无需再次加载所有变量。

我知道我可以使用system 运行系统命令,但是必须先终止命令,然后才能使用输出。我也知道我可以使用 CPython 并在文件上调用 PyRun_SimpleFileEx,但这将不得不再次重新加载所有变量

我没有任何代码可以显示,因为我不知道该怎么做。有什么方法可以做到这一点,而无需用 C++ 重写整个 python 脚本?

【问题讨论】:

  • 所以你有一个使用这些全局变量的方法,但你只想加载这些变量一次。对吗?
  • 是的,没错
  • 能否编辑脚本,将要多次调用的代码作为函数公开?
  • 我要运行几次的代码已经是Python中的一个函数了。但是,它依赖于一些加载缓慢的全局变量。我想从 C++ 程序中调用该函数。我希望这有助于澄清。

标签: python c++


【解决方案1】:

每个PyRun_* 函数都在__main__ 模块中运行,因此您定义的任何函数或变量都会保留以供将来执行。

例如,假设我们要多次运行此文件 (helper.py) 中的 do_it 函数:

from datetime import datetime as dt
from time import sleep
print("First load")

def do_it():
    print("Helper function called on demand: %s" % dt.now())
    sleep(1)

do_it()

我们可以简单地调用一次PyRun_SimpleFile,然后使用PyRun_SimpleString("do_it()\n");再次访问该函数。

#define PY_SSIZE_T_CLEAN
#include <Python.h>

int main(int argc, char *argv[])
{
    wchar_t *program = Py_DecodeLocale(argv[0], NULL);
    if (program == NULL) {
        fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
        exit(1);
    }
    Py_SetProgramName(program);  /* optional but recommended */
    Py_Initialize();
    FILE *fp = fopen("helper.py", "rb");
    PyRun_SimpleFile(fp, "helper.py");
    for (int i = 0; i < 10; i++) {
        PyRun_SimpleString("do_it()\n");
    }
    if (Py_FinalizeEx() < 0) {
        exit(120);
    }
    PyMem_RawFree(program);
    return 0;
}

请注意,这使用了“非常高级的嵌入”,因此仅限于评估字符串。对于更复杂的参数,您可能希望使用 "Pure embedding" 而不是从模块中获取 PyFunctionObject 并调用它。

最后,您可能想看看pybind11,它是 Python 和 C++ 之间的 C++11 桥梁。这应该使得获取 Python 函数并直接从 C++ 调用它变得非常容易。

【讨论】:

    猜你喜欢
    • 2021-12-02
    • 1970-01-01
    • 1970-01-01
    • 2011-10-11
    • 2014-05-20
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    • 1970-01-01
    相关资源
    最近更新 更多