Part of the reason I started to investigate this mechanism is because we are currently reliant on setting environment variables to communicate with GR:
GR uses its own plugin system and loads dynamic libraries itself:
Here we communicate the location of the GR binaries via the GRDIR.
My thought is that perhaps we could use this new API to communicate multiple directories to GR.
In trying out this API, I found something unpleasant. If someone calls SetDefaultDllDirectories with LOAD_LIBRARY_SEARCH_DEFAULT_DIRS, then it causes LoadLibraryExW to fail with LOAD_WITH_ALTERED_SEARCH_PATH.
julia> begin
wchar = append!(transcode(UInt16, raw"libdSFMT.dll"), 0x0000)
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x1000
LOAD_WITH_ALTERED_SEARCH_PATH = 0x8
status = @ccall "kernel32".SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS::UInt32)::Bool # GR.jl v0.70.1
handle = @ccall "kernel32".LoadLibraryExW(wchar::Ptr{UInt16}, C_NULL::Ptr{Nothing}, LOAD_WITH_ALTERED_SEARCH_PATH::UInt32)::Ptr{Nothing} # Julia
if handle == C_NULL
println(Libc.FormatMessage())
end
handle
end
The parameter is incorrect.
Ptr{Nothing} @0x0000000000000000
Everything loads fine if we use LOAD_LIBRARY_SEARCH_DEFAULT_DIRS.
julia> begin
wchar = append!(transcode(UInt16, raw"libdSFMT.dll"), 0x0000)
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x1000
LOAD_WITH_ALTERED_SEARCH_PATH = 0x8
status = @ccall "kernel32".SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS::UInt32)::Bool
handle = @ccall "kernel32".LoadLibraryExW(wchar::Ptr{UInt16}, C_NULL::Ptr{Nothing}, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS::UInt32)::Ptr{Nothing}
if handle == C_NULL
println(Libc.FormatMessage())
end
handle
end
Ptr{Nothing} @0x0000000000e20000
The main lesson from this is that we should not use SetDefaultDllDirectories since this causes Julia’s current use of LoadLibraryExW to fail when used with LOAD_WITH_ALTERED_SEARCH_PATH. The other thought is that using LOAD_WITH_ALTERED_SEARCH_PATH is fragile. Loading some plugin that invokes SetDefaultDllDirectories will cause Julia to be unable to dynamically load other dynamic libraries.
To make dynamic library loading more robust and and to take advantage of AddDllDirectory perhaps we could try to use LOAD_LIBRARY_SEARCH_DEFAULT_DIRS with LoadLibraryExW if loading with LOAD_WITH_ALTERED_SEARCH_PATH fails. That might look as follows.