提问人:sjohns 提问时间:10/19/2023 最后编辑:sjohns 更新时间:10/20/2023 访问量:51
调用 CFFI 函数时如何优雅地处理异常/崩溃?
How can I gracefully handle exceptions/crashes when calling a CFFI function?
问:
我正在使用 Python 的 CFFI 从 DLL 调用 C 函数。
from CFFI import FFI
my_ffi = FFI()
my_dll = my_ffi.dlopen(my_dll_path)
my_ffi.cdef('int my_func();')
my_c_int = my_dll.my_func()
有时,C 函数会崩溃、引发异常或这些异常的组合。这通常会导致调用 C 函数的 Python 脚本终止。
我希望能够做这样的事情:
try:
my_c_int = my_dll.my_func()
except SomeKindsOfExceptionsIncludingTheForeignFunctionCrashing:
handle_exception()
是否可以处理外部函数引发的异常以及外部函数中的崩溃?如果是这样,如何才能最好地完成?
编辑:具体来说,我想处理在外部函数中执行代码期间引发的异常以及它使用的库。我不想捕获和忽略硬件异常。我正在处理的一个典型异常是由套接字意外断开引起的。
我考虑过在单独的线程中调用 C 函数并监视该线程的超时。但是,C 函数实现了优化器的部分损失函数,因此我想避免每次调用 C 函数时启动新线程的开销。此外,一个新线程很混乱,感觉应该有一种更简单的方法来做到这一点。
我正在单独研究减少来自我的DLL的异常行为数量的方法,尽管这可能不会实现。
编辑:评论中建议了 SEH,但据我了解,这将发生在外部函数中,而不是在 Python 端。我的目标是能够使用 Python 来处理此类异常。这是对一个线程的响应,该线程似乎表明 ctypes 模块不支持 SEH:
如果解释器未在较低级别处理 OS 异常,或者 一个扩展模块,进程崩溃得很厉害。
但是,我正在使用 CFFI 模块,它的行为可能有所不同。
答:
您可以通过围绕 C++ 代码编写自己的 C 包装器来间接使用 CFFI 调用 C++ 代码并捕获 C++ 异常。为此,您需要在 API 模式下使用 CFFI 并在部件中编写包装器;然后使用 CFFI 调用此 C 包装器。set_source()
您也可以直接使用 CPython C API,但它仍然需要相同的 C 包装器:这两种解决方案都对 C++ 异常没有任何理智,因此您必须捕获并转换它们。
评论
fork()