-1

On Windows I have a DLL that we made ourselves which among other loads another DLL. The problem is that when using the DLL in Matlab with loadlibrary, calllib and unloadlibrary everything is fine.

In Python I tried to use ctypes and cffi, both with same results. I can load the DLL and call functions, but I cannot exit again. Python hangs, and I have to end the task from the Task Manager.

With ctypes I have tried to call

import _ctypes
_ctypes.FreeLibrary(lib._handle)

as suggested here Free the opened ctypes library in Python with no effect. Further, I tried to call explicit function to unload the other DLL.

Can anyone give a hint or solution to why it will not unload/hangs?

Community
  • 1
  • 1
Jørgen
  • 853
  • 9
  • 16
  • The linked duplicate has two misguided answers. For the accepted answer, note that the `_ctypes` extension module defines `dlclose` and `FreeLibrary`. These functions raise `OSError` when the library can no longer be freed, so there's no reason for Piotr's `isLoaded` function. Moreover, his statement that "ctypes keeps internally references to this handle" looks to be just made up. The instance `_handle` is only used for the repr. There's no reason to `del` the `CDLL` instance (i.e. to finalize it, assuming a single reference). – Eryk Sun Sep 23 '15 at 13:48

1 Answers1

-1

I found part of the answer here How can I unload a DLL using ctypes in Python?

Apperently one has to call call _ctypes.FreeLibrary directly.

# Release DLL(?)
handle= lib._handle
 _ctypes.FreeLibrary(handle)
Community
  • 1
  • 1
Jørgen
  • 853
  • 9
  • 16
  • You found the answer on the site. This question should be deleted or closed as a duplicate, not posted with the same answer. – Peter Wood Sep 23 '15 at 07:32
  • Whatever `del` is solving, I assure you it is doing nothing with regard to unloading the DLL. In my example, I did no such thing, yet obviously the `DLL_PROCESS_DETACH` code ran. Please read the source code for [`CDLL`](https://hg.python.org/cpython/file/v2.7.10/Lib/ctypes/__init__.py#l332). The lifetime of `CDLL` instances has nothing to do with freeing the library. ctypes *never* calls `FreeLibrary`. When Piotr says "ctypes keeps internally references to this handle", I'm not really sure what he means, but the obvious interpretation is wrong. – Eryk Sun Sep 23 '15 at 13:08
  • @eryksun You are absolutely right, I corrected my answer by removing the `del` call. It did not do anything. – Jørgen Sep 23 '15 at 14:05
  • Is it still hanging? Did you call `_ctypes.FreeLibrary` in a `while` loop until it raises `OSError`? The DLL keeps a per-process reference count that gets incremented for each `LoadLibrary` call in a process. The loader only calls `DLL_PROCESS_DETACH` and unmaps the DLL when the reference count is decremented to 0, i.e. if the DLL is loaded N times by `LoadLibrary`, then `FreeLibrary` has to be called N times as well. (Since a DLL can be mapped into multiple processes this doesn't necessarily unload it from the system page tables, so for example you still may not be able to delete the DLL.) – Eryk Sun Sep 23 '15 at 14:30
  • No its not hanging anymore. I tried calling `_ctypes.FreeLibrary` more than once and throws `WindowsError: [Error 126] The specified module could not be found` on the second call. Should/Would it throw `OSError`on other platforms than Windows? I am happy though, it works for me. Difficult to find out, since its not really documented. – Jørgen Sep 24 '15 at 13:39