强制ctypes.cdll.LoadLibrary()从文件中重新加载库 [英] forcing ctypes.cdll.LoadLibrary() to reload library from file
问题描述
我有以下代码
import ctypes
lib1 = ctypes.cdll.LoadLibrary("./mylib.so")
# modify mylib.so (code generation and compilation) or even delete it
lib2 = ctypes.cdll.LoadLibrary("./mylib.so")
问题是 lib2
是指原始共享库,而不是新共享库一。如果我在两次调用之间删除mylib.so,我不会出错。
The problem is that lib2
refers to the original shared library, not the new one. If I delete mylib.so between the calls I get no error.
使用 ctypes._reset_cache()
不会
我如何告诉 ctypes
实际上是从硬盘上重新加载库的?
How can I tell ctypes
to actually reload the library from the hard disk?
推荐答案
我不知道如何指示 ctypes 如何卸载库(找不到< a href = https://docs.python.org/3/library/ctypes.html#module-ctypes rel = nofollow noreferrer> [Python 3]:ctypes-Python的外部函数库
I don't know how to instruct ctypes how to unload a library (didn't find a way on [Python 3]: ctypes - A foreign function library for Python, but that doesn't mean that there isn't one).
可以通过强制加载器(减少库的引用计数并)卸载来手动完成此操作。通过 [man7]:DLCLOSE(3P)(也阅读 [man7]:DLOPEN(3)了解更多信息加载/卸载库)。
It can be done manually, by forcing the loader to (decrement the library's reference count and) unload it via [man7]: DLCLOSE(3P) (also read [man7]: DLOPEN(3) for additional info on loading / unloading libraries).
dll.c :
#include <stdio.h>
int func0(int arg0) {
int alter_factor = 2;
printf("From C - arg0: %d, alter_factor: %d\n", arg0, alter_factor);
return arg0 * alter_factor;
}
code.py :
#!/usr/bin/env python3
import sys
import ctypes
DLL_NAME = "./dll.so"
def handle_dll(dll_name=DLL_NAME):
dll_dll = ctypes.CDLL(dll_name)
func0_func = dll_dll.func0
func0_func.argtypes = [ctypes.c_int]
func0_func.restype = ctypes.c_int
return dll_dll, func0_func
def main():
dlclose_func = ctypes.CDLL(None).dlclose
dlclose_func.argtypes = [ctypes.c_void_p]
dlclose_func.restype = ctypes.c_int
dll, func0 = handle_dll()
res = func0(42)
print(res)
dlclose_func(dll._handle)
input("In another terminal, modify the C code (e.g. change `alter_factor`), recompile (gcc -fPIC -shared -o dll.so dll.c), and when done press ENTER here...")
dll, func0 = handle_dll()
res = func0(42)
print(res)
if __name__ == "__main__":
print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
main()
输出:
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q050964033]> python3 code.py
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
From C - arg0: 42, alter_factor: 2
84
In another terminal, modify the C code (e.g. change `alter_factor`), recompile (gcc -fPIC -shared -o dll.so dll.c), and when done press ENTER here...
From C - arg0: 42, alter_factor: 3
126
这篇关于强制ctypes.cdll.LoadLibrary()从文件中重新加载库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!