强制ctypes.cdll.LoadLibrary()从文件重新加载库

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了强制ctypes.cdll.LoadLibrary()从文件重新加载库相关的知识,希望对你有一定的参考价值。

我有以下代码

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 3]: ctypes - A foreign function library for Python上找到方法,但这并不意味着没有一个)。

它可以手动完成,强制加载器(减少库的引用​​计数)并通过[man7]: DLCLOSE(3P)卸载它(也可以读取[man7]: DLOPEN(3)以获取有关加载/卸载库的其他信息)。

dll.c:

#include <stdio.h>

int func0(int arg0) {
    int alter_factor = 2;
    printf("From C - arg0: %d, alter_factor: %d
", arg0, alter_factor);
    return arg0 * alter_factor;
}

code.朋友:

#!/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}
".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()从文件重新加载库的主要内容,如果未能解决你的问题,请参考以下文章

ctypes 加载具有依赖关系的 c 共享库

用百度ocr+微信截图实现文字识别

Leptonica - 应用 otsu 阈值后无法写入图像

WindowsError:[错误 126] 找不到指定的模块

Python直接调用C库的printf()函数打印一条消息

修改功能并保持代码的可操作性