cpython 启动文件,在Python中释放打开的ctypes库

I was wondering that, if I opened my own dll library compiled from custom c code, like this:

import ctypes

my_lib = ctypes.cdll.LoadLibrary('./my_dll.dll')

my_func = my_lib.my_func

# Stuff I want to do with func()

Do I need to close the my_lib object after use, like a file object? Will doing this make the code cleaner, more efficient, and more "pythonic"?

Thanks!

解决方案

Generally you shouldn't have to free a shared library. Consider that CPython doesn't provide a means to unload a regular extension module from memory. For example, importing sqlite3 will load the _sqlite3 extension and sqlite3 shared library for the life of the process. Unloading extensions is incompatible with the way CPython uses pointers as object IDs. Accessing a deallocated (and possibly reused) address would be undefined behavior.

If you need to unload or reload a shared library, and are confident that it's safe, the _ctypes extension module has POSIX dlclose and Windows FreeLibrary, which call the system functions of the same name. Both take the library handle as the single argument. This is the _handle attribute of a CDLL instance. If unloading the library fails, OSError is raised.

Both dlclose and FreeLibrary work by decrementing the handle's reference count. The library is unloaded when the count is decremented to 0. The count is initially 1 and gets incremented each time POSIX dlopen or Windows LoadLibrary is called for an already loaded library.

POSIX Example

#include

void __attribute__((constructor)) initialize()

{

printf("initialize\n");

}

void __attribute__((destructor)) finalize()

{

printf("finalize\n");

}

POSIX Python

>>> import ctypes

>>> lib1 = ctypes.CDLL('./lib.so')

initialize

>>> lib2 = ctypes.CDLL('./lib.so')

>>> lib1._handle == lib2._handle

True

>>> import _ctypes

>>> _ctypes.dlclose(lib1._handle)

>>> _ctypes.dlclose(lib1._handle)

finalize

>>> lib1 = ctypes.CDLL('./lib.so')

initialize

>>> _ctypes.dlclose(lib1._handle)

finalize

Windows Example

#include

#include

void initialize()

{

printf("initialize\n");

}

void finalize()

{

printf("finalize\n");

}

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._handle

True

>>> import _ctypes

>>> _ctypes.FreeLibrary(lib1._handle)

>>> _ctypes.FreeLibrary(lib1._handle)

finalize

>>> lib1 = ctypes.CDLL('./lib.dll')

initialize

>>> _ctypes.FreeLibrary(lib1._handle)

finalize

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值