2016-02-28 97 views
3

假設我想在Python中使用libc。這可以通過獲取Python中共享庫的絕對路徑

from ctypes import CDLL 
from ctypes.util import find_library 

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

很容易做到現在,我知道我可以使用ldconfig來獲得libc中的ABSPATH,但有從CDLL對象獲取它的方法嗎?有沒有可以用_handle完成的事情?

更新:好的。

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

我需要重新定義link_map結構然後?!

回答

3

在此上下文中的手柄基本上是對存儲器映射的庫文件的引用。

但也有實現你想要的OS功能的幫助下什麼什麼的存在方式。

windows: Windows爲此提供了一個稱爲GetModuleFileName的API。使用的一些示例已經是here

的Linux: 還有就是現有的用於此目的的dlinfo功能,見here


我玩過ctypes,這裏是我的基於Linux的系統的解決方案。到目前爲止,我對ctypes沒有任何知識,如果有任何改進的建議,我很感激他們。

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)