Reputation: 2405
I'm learning how to wrap c functions using Python's ctypes' and am able to wrap and call a function, but I can't figure out how to get the
errno` after there is an error. For this example, I'm wrapping inotify_add_watch. This isn't the full code, just an example of something that will cause an error:
import ctypes
c_lib = ctypes.cdll.LoadLibrary('libc.so.6')
inotify_add = c_lib.inotify_add_watch
inotify_add.argtypes = (ctypes.c_int, ctypes.c_char_p, ctypes.c_uint32)
inotify_add.restype = ctypes.c_int
# This will cause an EBADF error
inotify_add(32, b'/tmp', 1) # returns -1
And the documentation I linked says this will return -1
which it does, but that it also will set errno
appropriately. I cannot figure out how to access errno
now. If I try ctypes.get_errno()
, this just returns 0
. If I try to call c_lib.errno()
, this causes a segmentation error
, so that isn't working either. Is there a way I can retrieve errno
?
Upvotes: 0
Views: 881
Reputation: 178021
You have to get errno from the same CRT library that Python was built with. So for Python 3.7 on Windows. I don't have Linux handy to try, so hopefully this puts you in the right direction.
>>> dll = CDLL('ucrtbase',use_errno=True)
>>> get_errno()
0
>>> dll._access(b'nonexisting',0)
-1
>>> get_errno()
2
Errno 2 is ENOENT (No such file or directory) so it got set and looks correct.
A different CRT library has a different errno
instance so it isn't captured correctly by Python for use with set_errno()/get_errno()
.
Upvotes: 2