C ++调用Python如何处理SystemExit异常

问题描述

我有一个C ++代码,该代码使用PyRun_SimpleFileEx C API执行Python脚本。

py文件看起来像这样

import time

time.sleep(2)
raise SystemExit("Sorry,it is time to exit.")

通过调用quit()abort()之类的python工具也可以引发SystemExit

由于SystemExit继承自BaseException而不是Exception,因此它没有被捕获,并关闭了Python环境以及C ++应用程序。

有什么办法可以从C ++中捕获上述异常?

预先感谢 祝一切顺利 MB

解决方法

您可以创建一个wrapper.py并从中运行代码。

class ExceptionWrapper(Exception):
    def __init__(self,exc):
        self.exc = exc

def run_code(filename):
    try:
        exec(open(filename).read(),globals=globals(),locals=locals())
    except BaseException as ex:
        raise ExceptionWrapper(ex)

从C ++使用此包装器:

#include <Python.h>

int main() {
    Py_Initialize();
    PyObject * wrapper = PyImport_ImportModule("wrapper");
    if (!wrapper) {
        PyErr_Print();
        exit(1);
    }
    PyObject * res = PyObject_CallMethod(wrapper,"run_code","s","simple.py");
    if (!res) {
        PyErr_Print();
        // PyObject *type,*value,*traceback;
        // PyErr_Fetch(&type,&value,&traceback);
        // PyErr_NormalizeException(&type,&traceback);
        // or handle exception manually here
        // PyErr_Restore(type,value,traceback);
    }
    Py_XDECREF(res);
    printf("exit from C\n");
}

请注意,这只是一个POC,运行任意代码并不安全。

您可以修改包装器以接受文件描述符作为参数。

,

也许对其他人有用:

使用PyRun_File* C API系列可以使外部C ++应用程序保持不变(不关闭)。

该脚本将失败,并且该函数返回的PyObject指针将无效,以指示该情况