forcing ctypes.cdll.LoadLibrary() to reload library from file

前端 未结 2 1116
北海茫月
北海茫月 2020-12-20 23:49

I have the following code

import ctypes
lib1 = ctypes.cdll.LoadLibrary(\"./mylib.so\")
# modify mylib.so (code generation and compilation) or even delete it
         


        
相关标签:
2条回答
  • 2020-12-21 00:25

    Simplifying CristiFatis answer a bit, I wrote a close-library function. The following code can be used to develop in your shared library and call it (in the most recent version) from python.

    import ctypes
    def ctypesCloseLibrary(lib):
        dlclose_func = ctypes.CDLL(None).dlclose
        dlclose_func.argtypes = [ctypes.c_void_p]
        dlclose_func.restype = ctypes.c_int
    
        dlclose_func(lib._handle)
    
    if __name__== "__main__":
        lib = ctypes.cdll.LoadLibrary('./mylib.so')
    
        # do things with lib_MyClass
    
        ctypesCloseLibrary(lib)
    

    Just call ctypesCloseLibrary when you want lib to be reloadable by lib = ctypes.cdll.LoadLibrary('./mylib.so').

    0 讨论(0)
  • 2020-12-21 00:33

    I don't know how to instruct ctypes how to unload a library (didn't find a way on [Python 3]: ctypes - A foreign function library for Python, but that doesn't mean that there isn't one).

    It can be done manually, by forcing the loader to (decrement the library's reference count and) unload it via [man7]: DLCLOSE(3P) (also read [man7]: DLOPEN(3) for additional info on loading / unloading libraries).

    dll.c:

    #include <stdio.h>
    
    int func0(int arg0) {
        int alter_factor = 2;
        printf("From C - arg0: %d, alter_factor: %d\n", arg0, alter_factor);
        return arg0 * alter_factor;
    }
    

    code.py:

    #!/usr/bin/env python3
    
    import sys
    import ctypes
    
    
    DLL_NAME = "./dll.so"
    
    
    def handle_dll(dll_name=DLL_NAME):
        dll_dll = ctypes.CDLL(dll_name)
        func0_func = dll_dll.func0
        func0_func.argtypes = [ctypes.c_int]
        func0_func.restype = ctypes.c_int
        return dll_dll, func0_func
    
    
    def main():
        dlclose_func = ctypes.CDLL(None).dlclose
        dlclose_func.argtypes = [ctypes.c_void_p]
        dlclose_func.restype = ctypes.c_int
    
        dll, func0 = handle_dll()
        res = func0(42)
        print(res)
        dlclose_func(dll._handle)
        input("In another terminal, modify the C code (e.g. change `alter_factor`), recompile (gcc -fPIC -shared -o dll.so dll.c), and when done press ENTER here...")
        dll, func0 = handle_dll()
        res = func0(42)
        print(res)
    
    
    if __name__ == "__main__":
        print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
        main()
    

    Output:

    [cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q050964033]> python3 code.py
    Python 3.5.2 (default, Nov 23 2017, 16:37:01)
    [GCC 5.4.0 20160609] on linux
    
    From C - arg0: 42, alter_factor: 2
    84
    In another terminal, modify the C code (e.g. change `alter_factor`), recompile (gcc -fPIC -shared -o dll.so dll.c), and when done press ENTER here...
    From C - arg0: 42, alter_factor: 3
    126
    
    0 讨论(0)
提交回复
热议问题