18

I am loading a dll with ctypes like this:

lib = cdll.LoadLibrary("someDll.dll");

When I am done with the library, I need to unload it to free resources it uses. I am having problems finding anything in the docs regarding how to do this. I see this rather old post: How can I unload a DLL using ctypes in Python?. I am hoping there is something obvious I have not found and less of a hack.

Community
  • 1
  • 1
Doo Dah
  • 3,979
  • 13
  • 55
  • 74
  • 1
    I have, but, from the post I referenced: "i don't know, but i doubt that this unloads the dll. i'd guess it only removes the binding from the name in the current namespace (as per language reference) " I suspect this is true. I am fairly sure the resource I need freed are still open. – Doo Dah Oct 29 '12 at 20:28
  • Might be useful: [\[SO\]: forcing ctypes.cdll.LoadLibrary() to reload library from file (@CristiFati's answer)](https://stackoverflow.com/a/50986803/4788546), [\[SO\]: Unload shared library inside ctypes loaded shared library (@CristiFati's answer)](https://stackoverflow.com/a/52223168/4788546). – CristiFati Jan 11 '23 at 10:53

1 Answers1

23

The only truly effective way I have ever found to do this is to take charge of calling LoadLibrary and FreeLibrary. Like this:

import ctypes

# get the module handle and create a ctypes library object
libHandle = ctypes.windll.kernel32.LoadLibraryA('mydll.dll')
lib = ctypes.WinDLL(None, handle=libHandle)

# do stuff with lib in the usual way
lib.Foo(42, 666)

# clean up by removing reference to the ctypes library object
del lib

# unload the DLL
ctypes.windll.kernel32.FreeLibrary(libHandle)

Update:

As of Python 3.8, ctypes.WinDLL() no longer accepts None to indicate that no filename is being passed. Instead, you can workaround this by passing an empty string.

See https://bugs.python.org/issue39243

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 1
    My ctypes calls begin failing when I go down this route with this error: "ValueError: Procedure probably called with too many arguments (16 bytes in excess)" when I attempt to make a function call – Doo Dah Oct 29 '12 at 20:50
  • 1
    What calling convention is your function meant to use? `WinDLL` means `stdcall`. Is your lib `cdecl`? If so use `ctypes.CDLL` instead. – David Heffernan Oct 29 '12 at 20:52