2013-10-23 54 views
9

我有一個用於與C庫進行交互的Python 2.7 GUI。我在GUI中做了一堆設置,然後按「go」按鈕。然後,我正在查看結果,不再需要庫代碼。但我想在更改庫時保留所有的GUI狀態。我可以顯式關閉ctypes CDLL嗎?

我導入sodll與​​,這明顯打開文件供閱讀。但是,我想顯式關閉文件以重新編譯並覆蓋它。然後,當我再次按下「go」按鈕時,我想導入新版本。

在最糟糕的情況下,我可以將文件複製到tempfile.NamedTemporaryFile,但是我有處理打開幾十個文件,其中沒有一個可以清理。

我可以以某種方式顯式關閉文件句柄嗎?或者,我可以將文件內容讀入StringIO對象,並以某種方式指向​​那個?

回答

4

您需要關閉DLL的句柄才能首先發布,以便您可以使用該文件,您需要獲取庫的句柄,然後將它傳遞給Windows上的FreeLibrary,然後您可以執行所需的操作與DLL文件:

from ctypes import * 

file = CDLL('file.dll') 

# do stuff here 

handle = file._handle # obtain the DLL handle 

windll.kernel32.FreeLibrary(handle) 

預覽:

下面是測試DLL:

#include <windows.h> 
#include <stdio.h> 

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"); 
} 

預覽:

>>> 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 
在Linux上

您使用dlclose這將是:

from ctypes import * 

file = CDLL('./file.so') 

# do stuff here 

handle = file._handle # obtain the SO handle 

cdll.LoadLibrary('libdl.so').dlclose(handle) 

下面是一個類似的共享對象

#include <stdio.h> 

__attribute__((constructor)) void dlentry(void) { 
    puts("SO loaded"); 
} 

void function(void) { 
    puts("Hello"); 
} 

__attribute__((destructor)) void dlexit(void) { 
    puts("SO unloaded"); 
} 

預覽:

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