在Win32上将临时DLL加载到Python中

时间:2013-03-21 23:56:18

标签: python windows ctypes

我在各种Python代码库中看到的一个常见的习惯用法是在运行时动态生成/加载C函数:

import tempfile
import shutil
from ctypes import CDLL

workdir = tempfile.mkdtemp()
try:
    # Generate and write code in workdir
    # ...
    # Compile and link into an .so/.dylib/.dll
    # ...
    lib = CDLL(path_to_lib)
finally:
    shutil.rmtree(workdir)

虽然这似乎在* nix系统上工作得很好,但我不确定它在Win32上的效果如何。这是因为,根据我的经验,当临时目录中的.dll映射到进程时,无法取消链接。因此,rmtree将失败。

我可以使用哪些选项来确保在Win32上尽快删除.dll(及其所在的目录)(一旦基础lib已被gc或应用程序终止,以免留下临时残骸。)

1 个答案:

答案 0 :(得分:2)

使用Kernel32函数FreeLibrary取消映射DLL并减少其引用计数。要获得处理权限,您可以使用GetModuleHandleW,但_handle属性中已有{。}}。

编辑底层_ctypes模块已经为POSIX提供了此功能以及dlclose。如果出现错误,这些函数会引发WindowsError / OSError

>>> import os                               
>>> from ctypes import *  
>>> from _ctypes import FreeLibrary

>>> lib = CDLL('./lib.dll')
>>> hlib = lib._handle
>>> del lib
>>> FreeLibrary(hlib)

>>> os.remove('./lib.dll')
>>> os.path.exists('./lib.dll')
False