принуждение ctypes.cdll.LoadLibrary () для перезагрузки библиотеки из файла

1

У меня есть следующий код

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 чтобы на самом деле перезагрузить библиотеку с жесткого диска?

Теги:
dll
ctypes

1 ответ

1
Лучший ответ

Я не знаю, как проинструктировать 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
  • 0
    Это сработало. Благодарю. Однако этот метод может спровоцировать ошибки сегментации (что, по-видимому, является фактом). Также следует отметить, что нужно вызывать dlclose_func несколько раз, если библиотека была загружена несколько раз.
  • 0
    Да, попытка получить доступ к символу из незагруженной библиотеки - это неопределенное поведение (и иногда ожидается, что оно будет зависать). А также каждый dlopen вызов должен иметь свой dlaclose аналог. Но это все знания, связанные с загрузкой / выгрузкой библиотек.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню