Unload shared library inside ctypes loaded shared library

前端 未结 2 2030
小蘑菇
小蘑菇 2020-12-21 23:35

I\'m calling a so file from my python script. As far as I understand, I don\'t really need to free shared library that is opened in python using ctypes. However, inside my s

2条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-21 23:36

    example to unload dependencies

    Tested on Linux Fedora 32, Python 3.7.6 (anaconda), ctypes 1.1.0, g++ 10.2.1. Dependency is OpenCv (Version 4.2). More details here: How can I unload a DLL using ctypes in Python?

    code.cpp

    #include 
    #include  
    
    
    extern "C" int my_fct(int n)
    {
        cv::Mat1b mat = cv::Mat1b(10,8,(unsigned char) 1 );  // change 1 to test unloading
        
        return mat(0,1) * n;
    }
    

    Compile with g++ code.cpp -shared -fPIC -Wall -std=c++17 -I/usr/include/opencv4 -lopencv_core -o so_opencv.so

    Python code

    from sys import platform
    import ctypes
    
    
    class CtypesLib:
    
        def __init__(self, fp_lib, dependencies=[]):
            self._dependencies = [CtypesLib(fp_dep) for fp_dep in dependencies]
    
            if platform == "linux" or platform == "linux2":  # Linux
                self._dlclose_func = ctypes.cdll.LoadLibrary('').dlclose
                self._dlclose_func.argtypes = [ctypes.c_void_p]
                self._ctypes_lib = ctypes.cdll.LoadLibrary(fp_lib)
            elif platform == "win32":  # Windows
                self._ctypes_lib = ctypes.WinDLL(fp_lib)
    
            self._handle = self._ctypes_lib._handle
    
        def __getattr__(self, attr):
            return self._ctypes_lib.__getattr__(attr)
    
        def __del__(self):
            for dep in self._dependencies:
                del dep
    
            del self._ctypes_lib
    
            if platform == "linux" or platform == "linux2":  # Linux
                self._dlclose_func(self._handle)
            elif platform == "win32":  # Windows
                ctypes.windll.kernel32.FreeLibrary(self._handle)
    
    
    fp_lib = './so_opencv.so'
    
    ctypes_lib = CtypesLib(fp_lib, ['/usr/lib64/libopencv_core.so'])
    
    valIn = 1
    ctypes_lib.my_fct.argtypes = [ctypes.c_int]
    ctypes_lib.my_fct.restype = ctypes.c_int
    valOut = ctypes_lib.my_fct(valIn)
    print(valIn, valOut)
    
    del ctypes_lib
    

提交回复
热议问题