Libdl
— ModuleJulia中的Libdl模块提供了用于与共享库进行动态链接的专门和低级设施。虽然Julia本身通过ccall
内置支持链接到运行时共享库,但Libdl
通过提供额外的、更细粒度的控制来扩展此功能。它使用户能够在内存和文件系统中搜索共享库,手动加载它们并使用特定的运行时链接器选项,并以低级指针的形式查找库符号。
Dynamic Linker
Base.Libc.Libdl.dlopen
— Functiondlopen(libfile::AbstractString [, flags::Integer]; throw_error:Bool = true)
加载共享库,返回一个不透明的句柄。
常量 dlext
(.so
、.dll
或 .dylib
)给出的扩展可以从 libfile
字符串中省略,因为如果需要,它会自动附加。如果 libfile
不是绝对路径名,则会在数组 DL_LOAD_PATH
中搜索 libfile
,然后是系统加载路径。
可选的 flags 参数是 RTLD_LOCAL
、RTLD_GLOBAL
、RTLD_LAZY
、RTLD_NOW
、RTLD_NODELETE
、RTLD_NOLOAD
、RTLD_DEEPBIND
和 RTLD_FIRST
的按位或。这些会被转换为 POSIX(和/或 GNU libc 和/或 MacOS)dlopen 命令的相应标志(如果可能),或者在当前平台上如果指定的功能不可用则被忽略。默认标志是平台特定的。在 MacOS 上,默认的 dlopen
标志是 RTLD_LAZY|RTLD_DEEPBIND|RTLD_GLOBAL
,而在其他平台上,默认是 RTLD_LAZY|RTLD_DEEPBIND|RTLD_LOCAL
。这些标志的重要用途是指定动态库加载器在将库引用绑定到导出符号时的非默认行为,以及绑定的引用是放入进程本地还是全局范围。例如,RTLD_LAZY|RTLD_DEEPBIND|RTLD_GLOBAL
允许库的符号在其他共享库中可用,解决共享库之间存在依赖关系的情况。
如果找不到库,此方法会抛出错误,除非关键字参数 throw_error
被设置为 false
,在这种情况下,此方法返回 nothing
。
从 Julia 1.6 开始,此方法将以 @executable_path/
开头的路径替换为 Julia 可执行文件的路径,允许可重定位的相对路径加载。在 Julia 1.5 及更早版本中,这仅在 macOS 上有效。
Base.Libc.Libdl.dlopen_e
— Functiondlopen_e(libfile::AbstractString [, flags::Integer])
类似于 dlopen
,但返回 C_NULL
而不是引发错误。该方法现在已被弃用,建议使用 dlopen(libfile::AbstractString [, flags::Integer]; throw_error=false)
。
Base.Libc.Libdl.RTLD_NOW
— ConstantRTLD_DEEPBIND
RTLD_FIRST
RTLD_GLOBAL
RTLD_LAZY
RTLD_LOCAL
RTLD_NODELETE
RTLD_NOLOAD
RTLD_NOW
dlopen
的枚举常量。有关详细信息,请参阅您的平台手册页(如果适用)。
Base.Libc.Libdl.dlsym
— Functiondlsym(handle, sym; throw_error::Bool = true)
从共享库句柄中查找符号,成功时返回可调用的函数指针。
如果找不到符号,此方法会抛出错误,除非关键字参数 throw_error
被设置为 false
,在这种情况下,此方法返回 nothing
。
Base.Libc.Libdl.dlsym_e
— Functiondlsym_e(handle, sym)
从共享库句柄中查找符号,在查找失败时静默返回 C_NULL
。该方法现已弃用,建议使用 dlsym(handle, sym; throw_error=false)
。
Base.Libc.Libdl.dlclose
— Functiondlclose(handle)
关闭由句柄引用的共享库。
dlclose(::Nothing)
对于非常常见的使用模式
try
hdl = dlopen(library_name)
... do something
finally
dlclose(hdl)
end
我们定义了一个接受类型为 Nothing
的参数的 dlclose()
方法,以便用户代码在 library_name
未找到的情况下不必改变其行为。
Base.Libc.Libdl.dlext
— Constantdlext
当前平台上动态库的文件扩展名(例如 dll、dylib、so)。
Base.Libc.Libdl.dllist
— Functiondllist()
返回当前加载的动态库的路径,类型为 Vector{String}
。
Base.Libc.Libdl.dlpath
— Functiondlpath(handle::Ptr{Cvoid})
给定从 dlopen
获取的库 handle
,返回完整路径。
dlpath(libname::Union{AbstractString, Symbol})
获取库 libname
的完整路径。
示例
julia> dlpath("libjulia")
Base.Libc.Libdl.find_library
— Functionfind_library(names [, locations])
在 locations
列表中的路径、DL_LOAD_PATH
或系统库路径中(按此顺序)搜索 names
中的第一个库,该库可以成功地被 dlopen。成功时,返回值将是 names
中的一个(可能以 locations
中的一个路径为前缀)。这个字符串可以被赋值给一个 global const
,并在未来的 ccall
中用作库名称。失败时,它返回空字符串。
Base.DL_LOAD_PATH
— ConstantDL_LOAD_PATH
在调用 dlopen
时,将首先按顺序搜索此列表中的路径,然后再搜索系统位置以查找有效的库句柄。