【发布时间】:2019-03-11 15:11:32
【问题描述】:
我正在从 C 执行以下 Python 函数:
Python:
def runLoop(self):
try:
while True:
print("working")
time.sleep(1) # Delay for 1 second.
self.incrementcounter()
except:
print("caught exception")
C:
//Here we register traceFunction to give us a hook into the python
PyEval_SetProfile((Py_tracefunc)traceFunction, NULL);
//Abort interrupt reset to false
m_interruptRequest = false;
//Call the runLoop method
const char *szName = "runLoop";
PyObject_CallMethod(m_pyObject, szName, nullptr);
在这个循环的中间,我想从 C 中注入一个异常来中止循环,但也在 Python 中的 try/except 中处理异常。正如在 cmets 中提到的,我在 C 中注册了一个名为 tracer 的分析函数,能够从 C 中注入异常。下面的代码注入异常并杀死程序,因为它没有在 try/except 中捕获。
//Tracer 函数回调挂钩到 Python 执行。我们在这里处理暂停、恢复和中止请求。
void PythonRunner::tracer(void)
{
...
//Abort requested
else if (true == interruptRequested())
{
PyErr_SetString(PyExc_Exception, "ABORT");
}
}
有谁知道我如何从 C 中抛出异常以在 Python 中处理?谢谢
更新:在@zwol 和这篇文章 stackoverflow.com/questions/1420957/stopping-embedded-python 的帮助下,我找到了解决方案。关键是向 python 添加一个挂起的调用,例如
int PythonRunner::tracer(PyObject *, _frame *, int, PyObject *)
{
...
//Abort requested
else if (true == _instance->interruptRequested())
{
Py_AddPendingCall(&PythonRunner::raiseException, NULL);
}
return 0;
}
int PythonRunner::raiseException(void *)
{
PyErr_SetString(PyExc_KeyboardInterrupt, "Abort");
return -1;
}
【问题讨论】: