Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
820 views
in Technique[技术] by (71.8m points)

python - forcing ctypes.cdll.LoadLibrary() to reload library from file

I have the following code

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")

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.

Using ctypes._reset_cache() does not help.

How can I tell ctypes to actually reload the library from the hard disk?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

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
", 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}
".format(sys.version, sys.platform))
    main()

Output:

[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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...