简体   繁体   中英

Is it possible to raise a Python exception inside a ctypes callback that is called from C?

I have a shared library that I've wrapped using ctypes . The library exposes function pointers that can be used to modify its error-handling behaviour. Rather than simply printing a warning or terminating the process with exit(1) , I'd like to raise a Python exception which could be caught and handled on the Python side.

Here's a sketch of what I'm trying to do:

import ctypes

mylib = ctypes.cdll.LoadLibrary('mylib.so')

error_handler_p = ctypes.c_void_p.in_dll(mylib, 'error_handler')

@ctypes.CFUNCTYPE(None, ctypes.c_char_p)
def custom_error_handler(message):
    raise RuntimeError(message)


error_handler_p.value = ctypes.cast(custom_error_handler, ctypes.c_void_p).value


try:
    mylib.do_something_bad()
except RuntimeError:
    # maybe handle the exception here

At the moment it seems as though the exception is being raised within the callback, since I see a traceback with the expected error message in my STDERR. However, this exception does not seem to propagate up to the calling Python process, since the exception never gets caught and the calling process terminates normally.

You'd have to use the ctypes.PyDLL() class (via the ctypes.pydll loader) to access your library, and your C code would have to use the Python C API . You 'raise' an exception in C code by calling one of the PyErr_* functions , and then returning -1 to flag an error from the function. The PyDLL() class will then check for an exception being set.

You can't use any of the other loaders. Note that the PyDLL() loader also doesn't release the GIL; that would be the responsibility of your extension instead (use the macros supplied by the Python API headers ).

Note that since you already have to use the Python API just to raise exceptions, you may as well expose your C code as a proper Python extension.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM