У меня есть следующий код
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 между вызовами, я не получу ошибки.
Использование ctypes._reset_cache()
не помогает.
Как я могу сказать ctypes
чтобы на самом деле перезагрузить библиотеку с жесткого диска?
Я не знаю, как проинструктировать ctypes как выгрузить библиотеку (не нашел способ на [Python]: ctypes - библиотека внешних функций для Python, но это не значит, что ее нет).
Это можно сделать вручную, заставив загрузчика (уменьшив счетчик ссылок библиотеки) и выгрузив его через [man7]: DLCLOSE (3P) (также прочитайте [man7]: DLOPEN (3) для получения дополнительной информации о библиотеках загрузки/разгрузки),
code.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:
import sys
import ctypes
DLL_NAME = "./dll.so"
def handle_lib(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_lib()
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 code.c), and when done press ENTER here...")
dll, func0 = handle_lib()
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 code.c), and when done press ENTER here... From C - arg0: 42, alter_factor: 3 126
dlopen
вызов должен иметь свойdlaclose
аналог. Но это все знания, связанные с загрузкой / выгрузкой библиотек.