jpcgt
jpcgt

Reputation: 2248

Cleanly unload shared library and start over with Python CFFI

I'm setting up and opening a DLL like this:

from cffi import FFI
ffi = FFI()

api_path = '/path_to/api.h'
lib_path = '/path_to/lib.so'
with open(api_path) as f:
   ffi.cdef(f.read())
mylib = ffi.dlopen(lib_path)

myfunc_c = ff.callback('int (char *)', myfunc)
#etc...

How can I close the library and open it again? If I do

del mylib

and try the above code again I get CDefError: cannot parse ... when attempting ffi.cdef().

I've seen some examples for ctypes using dlclose() but can't find an equivalent for CFFI.

Thanks.

Upvotes: 2

Views: 1395

Answers (2)

Catskul
Catskul

Reputation: 19239

dlclose(lib) exists, but only for the out-of-line/precompiled FFIs.

http://cffi.readthedocs.io/en/latest/cdef.html#ffi-dlopen-loading-libraries-in-abi-mode

Upvotes: 1

Armin Rigo
Armin Rigo

Reputation: 12900

Sorry, CFFI has no way to call explicitly the C-level dlclose(). It is only called implicitly if the library object goes out of scope. Also, the ffi object keeps this library alive, so ffi needs to go out of scope too.

If you really want to do it, you need to make sure all references to mylib and ffi are gone, and call gc.collect(). (If you want then to reload, you need to start again with a fresh ffi = FFI().)

The next version of CFFI might add something like ffi.close_libraries() that unloads the libraries loaded in this ffi object.

EDIT: it won't work for libraries loaded with verify() on CPython, because these ones are regular CPython C extension modules, and CPython never unloads its C extension modules. This means that the general ffi.close_libraries() idea might be doomed...

Upvotes: 2

Related Questions