假设我要创建Common Lisp应用程序中使用的当前动态库的转储。给定cffi:list-foreign-libraries的结果,我如何获得外国图书馆的绝对路径?
如果给定的解决方案可以是可移植的操作系统或至少是CL实现的,那应该很好。
答案 0 :(得分:3)
经过一番调查,看来一旦加载了库,表示该库的pathname
实例的foreign-library
槽就被修改为指向解析的目标文件路径,仅当文件不在标准系统位置时才是绝对的。例如:
(cffi:list-foreign-libraries :loaded-only t)
=> (#<CFFI:FOREIGN-LIBRARY LIBSDL2 "libSDL2-2.0.so.0"> ...)
现在只需访问路径名插槽即可:
(mapcar #'cffi:foreign-library-pathname *)
=> (#P"libSDL2-2.0.so.0" ...)
但是在这里,您可以看到路径名不是绝对的。这是因为当CFFI内部调用cffi::%load-foreign-library
时(经过一点跟踪)时,它带有以下参数:
(cffi::%load-foreign-library "libSDL2-2.0.so.0" "libSDL2-2.0.so.0")
...,该实现使用系统的隐式查找机制(例如dlopen
)找到了目标文件。
cffi::%load-foreign-library
在不同平台上的实现方式有所不同,例如,对于SBCL,由dlopen
获得的指针存储在SB-SYS:*SHARED-OBJECTS*
内部的对象中,但是直到I知道没有一种便携式方法可以从中检索正在加载的库的路径。