2013-10-23 58 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 
>>> 
相关问题