You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在无PyRun_*系列接口的C++应用中执行.py文件

无PyRun_*系列接口时执行Python脚本的解决方案

适用场景:目标应用已嵌入Python解释器核心,但未暴露PyRun_SimpleString等PyRun_*系列封装接口

方案1:通过底层Python核心API编译执行源码

这是兼容性最高的方案,Python核心底层的编译、执行接口几乎不会被裁剪,无需改动原有脚本:

  • 核心执行步骤:
    1. 若目标应用未初始化Python解释器,先调用Py_Initialize()完成初始化
    2. 读取目标.py文件的全部内容到内存缓冲区
    3. 调用Py_CompileString()将源码编译为可执行的代码对象,第三个参数传入Py_file_input标记适配完整脚本的编译规则
    4. 调用PyEval_EvalCode()执行生成的代码对象,可直接使用当前全局命名空间,也可新建独立字典作为命名空间避免全局污染
    5. 执行完成后手动释放所有PyObject对象的引用,避免内存泄漏
  • 参考C++代码片段:
// 入参说明:py_file_path为目标.py文件路径
void run_py_script(const char* py_file_path) {
    // 1. 读取脚本内容到内存
    FILE* fp = fopen(py_file_path, "r");
    fseek(fp, 0, SEEK_END);
    long buf_len = ftell(fp);
    rewind(fp);
    char* code_buf = (char*)malloc(buf_len + 1);
    fread(code_buf, 1, buf_len, fp);
    code_buf[buf_len] = '\0';
    fclose(fp);

    // 2. 编译为代码对象
    PyObject* code_obj = Py_CompileString(code_buf, py_file_path, Py_file_input);
    free(code_buf);
    if (!code_obj) {
        PyErr_Print();
        return;
    }

    // 3. 执行代码对象
    PyObject* global_ns = PyEval_GetGlobals();
    PyObject* local_ns = PyDict_New();
    PyObject* exec_res = PyEval_EvalCode((PyCodeObject*)code_obj, global_ns, local_ns);

    // 4. 资源释放
    Py_XDECREF(exec_res);
    Py_DECREF(local_ns);
    Py_DECREF(code_obj);
}

方案2:预编译脚本为C扩展模块

如果目标应用的Python解释器裁剪力度极大,连Py_CompileString接口都未暴露,可提前把Python脚本转成C扩展:

  • 操作步骤:
    1. 用Cython或者Nuitka将目标.py脚本编译为对应平台的Python C扩展文件(Windows下为.pyd,Linux/macOS下为.so)
    2. 调用PySys_GetObject("path")获取Python模块搜索路径列表,将扩展文件所在目录追加到搜索路径中
    3. 调用PyImport_ImportModule("你的模块名")加载扩展,加载过程中会自动执行模块顶层的所有代码
    4. 若需要调用脚本内的特定函数,通过PyObject_GetAttrString()获取函数对象后,用PyObject_CallObject()触发调用即可

方案3:子进程独立执行(极端场景适用)

如果目标应用几乎没有暴露任何Python核心API,直接用打包工具把脚本打包为独立可执行文件:

  • 用PyInstaller、cx_Freeze等工具将.py脚本打包为单文件可执行程序
  • 在目标应用内通过系统API创建子进程执行该可执行文件,需要数据交互的话可以通过管道、共享内存、本地Socket等方式实现跨进程通信

内容的提问来源于stack exchange,提问作者0x00BAD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 01:45:03