Reputation: 2426
A common idiom I have seen in various Python code bases to dynamically generate/load a C function at runtime is:
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)
While this appears to work quite nicely on *nix systems I am unsure how well it will work on Win32. This is because, in my experience, when the .dll inside the temporary directory is mapped into the process it is not possible to unlink it. Hence, rmtree
will fail.
What options are available to me to ensure that on Win32 the .dll (and the directory in which it resides) are deleted ASAP (so as soon as the underlying lib
has been gc'ed or when the application terminates so as not to leave temporary cruft about).
Upvotes: 4
Views: 371
Reputation: 34270
Use the Kernel32 function FreeLibrary
to unmap the DLL and decrement its reference count. To get the handle you can use GetModuleHandleW
, but it's already available in the _handle
attribute.
Edit: The underlying _ctypes
module already provides this function as well as dlclose
for POSIX. If there's an error these functions raise 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
Upvotes: 2