在 Python 中使用 ctypes.util.find_library 获取库的完整路径

Her*_*nan 5 python linux macos ctypes shared-libraries

在 Python 中,ctypes.util.find_library 可用于以类似于编译器的方式定位库。在 Mac OSX 中,该函数返回完整路径名。但在linux中,只返回文件名。(这是文档

有没有办法在linux中获取完整路径?

小智 3

您可以使用以下命令加载库并迭代加载的库dl_iterate_phdr

#!python
from ctypes import *
from ctypes.util import find_library

# this struct will be passed as a ponter,
# so we don't have to worry about the right layout
class dl_phdr_info(Structure):
  _fields_ = [
    ('padding0', c_void_p), # ignore it
    ('dlpi_name', c_char_p),
                            # ignore the reset
  ]


# call back function, I changed c_void_p to c_char_p
callback_t = CFUNCTYPE(c_int,
                       POINTER(dl_phdr_info), 
                       POINTER(c_size_t), c_char_p)

dl_iterate_phdr = CDLL('libc.so.6').dl_iterate_phdr
# I changed c_void_p to c_char_p
dl_iterate_phdr.argtypes = [callback_t, c_char_p]
dl_iterate_phdr.restype = c_int


def callback(info, size, data):
  # simple search
  if data in info.contents.dlpi_name:
    print(info.contents.dlpi_name)
  return 0

if __name__ == '__main__':
  # the target lib we want to find
  target_lib = find_library('xml2')
  print(target_lib)
  # load it
  lib = CDLL(target_lib)
  # iterate over the loaded libs
  dl_iterate_phdr(callback_t(callback), target_lib)
Run Code Online (Sandbox Code Playgroud)

例如:

$ python test.py 
libxml2.so.2
/usr/lib/libxml2.so.2
$ 
Run Code Online (Sandbox Code Playgroud)

  • @Hernan:在Linux上,`find_library`首先尝试在函数[`_findSoname_ldconfig`](http://hg.python.org/cpython/file/3a1db0d2747e/Lib/ctypes/中解析`/sbin/ldconfig -p` util.py#l214)。它使用的正则表达式会影响当前进程是 32 位还是 64 位。如果您不想首先加载库,可以使用返回完整路径的修改版本。 (2认同)