Can I explicitly close a ctypes CDLL?

前端 未结 1 1219
终归单人心
终归单人心 2021-02-19 08:21

I have a Python 2.7 GUI for interacting with a C library. I do a bunch of setup in the GUI, then I press \"go\" button. Then, I\'m looking at results and no longer need the libr

1条回答
  •  谎友^
    谎友^ (楼主)
    2021-02-19 08:40

    You need to close the handle to the DLL so it released first so you can work with the file, you need to get the handle of the library and then pass it to FreeLibrary on Windows, then you can do what you need with the DLL file:

    from ctypes import *
    
    file = CDLL('file.dll')
    
    # do stuff here
    
    handle = file._handle # obtain the DLL handle
    
    windll.kernel32.FreeLibrary(handle)
    

    preview:

    Here is a test DLL:

    #include 
    #include 
    
    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
    
      switch( fdwReason ) {
        case DLL_PROCESS_ATTACH:
          puts("DLL loaded");
        break;
    
        case DLL_PROCESS_DETACH:
          puts("DLL unloaded");
        break;
    
        case DLL_THREAD_ATTACH:
        break;
    
        case DLL_THREAD_DETACH:
        break;
      }
    
      return TRUE;
    }
    
    __declspec(dllexport) void function(void) {
      puts("Hello");
    }
    

    preview:

    >>> from ctypes import *
    >>>
    >>> file = CDLL('file.dll')
    DLL loaded
    >>>
    >>> # now it's locked
    ...
    >>> file.function()
    Hello
    0
    >>> windll.kernel32.FreeLibrary(file._handle)
    DLL unloaded
    1
    >>> # not it's unlocked
    

    on Linux you use dlclose it would be:

    from ctypes import *
    
    file = CDLL('./file.so')
    
    # do stuff here
    
    handle = file._handle # obtain the SO handle
    
    cdll.LoadLibrary('libdl.so').dlclose(handle)
    

    Here is a similar shared object:

    #include 
    
    __attribute__((constructor)) void dlentry(void) {
      puts("SO loaded");
    }
    
    void function(void) {
      puts("Hello");
    }
    
    __attribute__((destructor)) void dlexit(void) {
      puts("SO unloaded");
    }
    

    preview:

    >>> from ctypes import *
    >>> 
    >>> file = CDLL('./file.so')
    SO loaded
    >>> 
    >>> file.function()
    Hello
    6
    >>> cdll.LoadLibrary('libdl.so').dlclose(file._handle)
    SO unloaded
    0
    >>> 
    

    0 讨论(0)
提交回复
热议问题