在Python中释放打开的ctypes库

在Python中释放打开的ctypes库,第1张

在Python中释放打开的ctypes库

通常,您不必释放共享库。考虑到CPython没有提供从内存中卸载常规扩展模块的方法。例如,导入sqlite3将在整个过程中加载_sqlite3扩展名和sqlite3共享库。卸载扩展与CPython使用指针作为对象ID的方式不兼容。访问已释放地址(并可能重用)的地址将是未定义的行为。

如果您需要卸载或重新加载共享库,并且确信它是安全的,则_ctypes扩展模块具有POSIX

dlclose
和Windows
FreeLibrary
,它们可以调用相同名称的系统函数。两者都将库句柄作为单个参数。这是实例的
_handle
属性
CDLL
。如果卸载库失败,
OSError
则会引发。

双方

dlclose
FreeLibrary
通过减小手柄的引用计数工作。当计数递减为0时,库将被卸载。计数最初为1,并且每次为已加载的库调用POSIX
dlopen
或Windows时,计数都会增加
LoadLibrary

POSIX示例

#include <stdio.h>void __attribute__((constructor)) initialize(){    printf("initializen");}void __attribute__((destructor)) finalize(){    printf("finalizen");}

POSIX Python

>>> import ctypes>>> lib1 = ctypes.CDLL('./lib.so')initialize>>> lib2 = ctypes.CDLL('./lib.so')>>> lib1._handle == lib2._handleTrue>>> import _ctypes>>> _ctypes.dlclose(lib1._handle)>>> _ctypes.dlclose(lib1._handle)finalize>>> lib1 = ctypes.CDLL('./lib.so')initialize>>> _ctypes.dlclose(lib1._handle)finalize

Windows示例

#include <stdio.h>#include <windows.h>void initialize(){    printf("initializen");}void finalize(){    printf("finalizen");}BOOL WINAPI DllMain(HINSTANCE hinstDLL,         DWORD fdwReason,         LPVOID lpReserved){    switch(fdwReason)     {         case DLL_PROCESS_ATTACH: initialize(); break;        case DLL_PROCESS_DETACH: finalize();    }    return TRUE;}

Windows Python

>>> import ctypes>>> lib1 = ctypes.CDLL('./lib.dll')initialize>>> lib2 = ctypes.CDLL('./lib.dll')>>> lib1._handle == lib2._handleTrue>>> import _ctypes>>> _ctypes.FreeLibrary(lib1._handle)>>> _ctypes.FreeLibrary(lib1._handle)finalize>>> lib1 = ctypes.CDLL('./lib.dll')  initialize>>> _ctypes.FreeLibrary(lib1._handle)finalize


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5647978.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-16
下一篇2022-12-16

发表评论

登录后才能评论

评论列表(0条)

    保存