Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get absolute path of shared library in Python

Tags:

python

c

dll

Let's say I wanted to use libc in Python. This can be easily done by

from ctypes import CDLL
from ctypes.util import find_library

libc_path = find_library('c')
libc = CDLL(libc_path)

Now, I know I could use ldconfig to get libc's abspath, but is there a way to acquire it from the CDLL object? Is there something that can be done with its _handle?

Update: Ok.

libdl = find_library('dl')
RTLD_DI_LINKMAP = 2
//libdl.dlinfo(libc._handle, RTLD_DI_LINKMAP, ???)

I need to redefine the link_map struct then?!

like image 943
cmz Avatar asked Feb 28 '16 12:02

cmz


People also ask

How do you find the absolute path of a Python module?

To get an absolute path in Python you use the os. path. abspath library. Insert your file name and it will return the full path relative from the working directory including the file.

How do I get the full path of a file in Python?

To get current file's full path, you can use the os. path. abspath function. If you want only the directory path, you can call os.

What is absolute and relative path in Python?

Absolute and Relative file pathsAn absolute file path describes how to access a given file or directory, starting from the root of the file system. A file path is also called a pathname. Relative file paths are notated by a lack of a leading forward slash.


1 Answers

A handle in this context is basically a reference to the memory mapped library file.

However there are existing ways to achieve what what you want with the help of OS functions.

windows: Windows provides an API for this purpose called GetModuleFileName. Some example of usage is already here.

linux: There is existing a dlinfo function for this purpose, see here.


I played around with ctypes and here is my solution for linux based Systems. I have zero knowledge of ctypes so far, if there are any suggestions for improvement I appreciate them.

from ctypes import *
from ctypes.util import find_library

#linkmap structure, we only need the second entry
class LINKMAP(Structure):
    _fields_ = [
        ("l_addr", c_void_p),
        ("l_name", c_char_p)
    ]

libc = CDLL(find_library('c'))
libdl = CDLL(find_library('dl'))

dlinfo = libdl.dlinfo
dlinfo.argtypes  = c_void_p, c_int, c_void_p
dlinfo.restype = c_int

#gets typecasted later, I dont know how to create a ctypes struct pointer instance
lmptr = c_void_p()

#2 equals RTLD_DI_LINKMAP, pass pointer by reference
dlinfo(libc._handle, 2, byref(lmptr))

#typecast to a linkmap pointer and retrieve the name.
abspath = cast(lmptr, POINTER(LINKMAP)).contents.l_name

print(abspath)
like image 100
Konstantin W Avatar answered Oct 04 '22 09:10

Konstantin W