-
Notifications
You must be signed in to change notification settings - Fork 81
Description
Currently, we set ENV["PATH"] on Windows since we need to communicate the DLL search path to GR so that it can dynamically load plugins.
Line 38 in 8b18b19
| ENV["PATH"] = join((lp, get(ENV, "PATH", "")), ';') |
The normal Windows search order is specified in the documentation with PATH being sixth in the priority list.
If SafeDllSearchMode is disabled, the search order is as follows:
The directory from which the application loaded.
- The current directory.
- The system directory. Use the GetSystemDirectory function to get the path of this directory.
- The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
- The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
- The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified 6. by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
As @giordano pointed out, this "looks like a bad idea".
The GR plugin loading code is located here:
https://github.com/sciapp/gr/blob/9aa4f55f75101b76ba8e4406b78601e410642cc6/lib/gks/plugin.c#L46-L55
#ifdef _WIN32
handle = LoadLibrary(pathname);
if (handle == NULL)
{
grdir = gks_getenv("GRDIR");
if (grdir == NULL) grdir = GRDIR;
snprintf(grbin, MAXPATHLEN, "%s/bin", grdir);
SetDllDirectory(grbin);
handle = LoadLibrary(pathname);
}Noticeably, this uses SetDllDirectory which maps to either SetDllDirectoryA or SetDllDirectoryW based on the value of the environment variable GRDIR.
Setting GRDIR works for a single directory. The following works in VSCode after commenting out line 38 of funcptrs.jl above.
julia> using GR
julia> x = 0:2π/360:2π; y = sin.(x);
julia> ENV["GRDIR"] = dirname(dirname(GR.GRPreferences.GR_jll.libGR_path))
"~\\.julia\\artifacts\\e40afe22fcfc9fe1caea4af17a4016e7ef36cd66"
julia> plot(x,y) # No Error
julia> contains(ENV["PATH"], ENV["GRDIR"])
falseIf we did not set GRDIR, this error occurs: GKS: svgplugin.dll: can't load library, error 126 (0x7e).
While setting GRDIR for a single directory works, there may be many directories to include in the DLL search path:
julia> length(GR.GRPreferences.GR_jll.LIBPATH_list)
35One strategy then would be for us to call SetDllDirectoryA directly. This works in VSCode:
julia> using GR
julia> kernel32 = :kernel32
:kernel32
julia> @ccall kernel32.SetDllDirectoryA(dirname(GR.GRPreferences.GR_jll.libGR_path)::Cstring)::UInt8
0x01
julia> x = 0:2π/360:2π; y = sin.(x);
julia> plot(x,y) # No error
julia> haskey(ENV, "GRDIR")
false
julia> contains(ENV["PATH"], dirname(dirname(GR.GRPreferences.GR_jll.libGR_path)))
falseWe could of course do this for all directories in LIBPATH_list. This also works in VSCode.
julia> using GR
julia> kernel32 = :kernel32
:kernel32
julia> all([@ccall kernel32.SetDllDirectoryA(d::Cstring)::Bool for d in GR.GRPreferences.GR_jll.LIBPATH_list])
true
julia> x = 0:2π/360:2π; y = sin.(x);
julia> plot(x,y)cc:@t-bltg