If the object specified by filename has dependencies on other shared objects, then these are also automatically loaded by the dynamic linker using the same rules. (This process may occur recursively, if those objects in turn have dependencies, and so on.)
...
If the same shared object is loaded again with dlopen(), the same object handle is returned. The dynamic linker maintains reference counts for object handles, so a dynamically loaded shared object is not deallocated until dlclose() has been called on it as many times as dlopen() has succeeded on it. Any initialization returns (see below) are called just once.
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q052179325]> ls
code.py dll.c
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q052179325]> gcc -fPIC -shared -o dll.so dll.c
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q052179325]> python3 ./code.py
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
Loading a dll via `ctypes`, then delete the object. The dll is not unloaded. Call `dlclose` to unload. A 2nd call will fail.
<CDLL './dll.so', handle 1d7aa20 at 0x7fa38715f240>
dlclose returned 0
dlclose returned -1
Use `ctypes` to load the dll twice. The dll is not actually loaded only the 1st time (both have the same handle), but its ref count is increased. `dlclose` must be also called twice.
<CDLL './dll.so', handle 1de2c80 at 0x7fa38715f240>
<CDLL './dll.so', handle 1de2c80 at 0x7fa38715f278>
dlclose returned 0
dlclose returned 0
dlclose returned -1
Load a dll via `ctypes`, and load one of its funcs. Try calling it before and after unloading the dll.
<CDLL './dll.so', handle 1de39c0 at 0x7fa38715f8d0>
[dll.c] (5) - [test]
test returned 0
dlclose returned 0
Segmentation fault (core dumped)
规则在您自己之后清理总是适用的(尽管现代技术为您解决了清洁方面的问题)。在
[Python 3.5]: ctypes - A foreign function library for Python包含很多有用的信息,应该是你的朋友。在
ctypes在加载.dll时使用dlopen。正如我所注意到的,它不调用相应的dlclose,这意味着.dll(以及加载时加载的所有依赖项)将保留在内存中,直到进程终止(或显式卸载)。在
从[man7]: DLOPEN(3):
所以,我认为你不会有问题(当然,一切都取决于上下文)。正如您所注意到的,多次加载一个库并不是每次都加载它,因此耗尽内存的机会非常小(除非您加载大量不同的.dll,每个都有很多不同的依赖项)。在
我能想到的一个例子是加载一个使用另一个.dll的符号的.dll。如果该符号也在之前加载的另一个(3rd).dll中定义,则代码的行为将与预期不同。在
无论如何,您可以手动卸载(或者更好:减少其refcount)a.dll(我不确定这如何符合推荐的方法或最佳实践),如下例所示。在
dll.c:
代码.py:
^{pr2}$输出:
相关问题 更多 >
编程相关推荐