Skip to content

Commit

Permalink
change loadLibrary on Windows to LoadLibraryA + LoadLibraryExA
Browse files Browse the repository at this point in the history
- try LoadLibraryA first in any case
- try LoadLibraryExA if that failed
- print error from both, unless second failed with invalid parameter error
- see also #759 and #760
  • Loading branch information
svigerske committed Apr 22, 2024
1 parent eaf02be commit 43a6341
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 12 deletions.
2 changes: 1 addition & 1 deletion ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ More detailed information about incremental changes can be found in the
### 3.14.16 (2024-04-22)

- Fixed load of linear solver libraries at runtime on Windows, which got
broken for relative paths (the default) in 3.14.15 [#759].
broken for relative paths (the default) in 3.14.15 [#759, #760].

### 3.14.15 (2024-04-10)

Expand Down
33 changes: 22 additions & 11 deletions src/Common/IpLibraryLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,23 +50,34 @@ void LibraryLoader::loadLibrary()
}

#ifdef HAVE_WINDOWS_H
/* if absolute path, then use LoadLibraryExA with LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR to find
* dependencies of library in same directory
* otherwise, use standard search paths (which includes PATH)
libhandle = (void*)LoadLibraryA(libname.c_str());

if( libhandle != NULL )
return;

std::stringstream s;
s << "Error " << GetLastError() << " while loading DLL " << libname << " via LoadLibraryA: ";
addLastError(s);

/* try again with LoadLibraryExA
* due to the use of LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR, this will always fail with an invalid parameter error (87) if libname is a relative path
*/
if( libname.length() > 2 && libname[1] == ':' )
libhandle = (void*)LoadLibraryExA(libname.c_str(), NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
else
libhandle = (void*)LoadLibraryA(libname.c_str());
libhandle = (void*)LoadLibraryExA(libname.c_str(), NULL, LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);

if( libhandle == NULL )
if( libhandle != NULL )
return;

/* skip message if LoadLibraryExA failed with invalid parameter error
* do not confuse user just because we were too lazy to check what kind of path libname is
*/
if( GetLastError() != 87 )
{
std::stringstream s;
s << "Error " << GetLastError() << " while loading DLL " << libname << ": ";
s << "Error " << GetLastError() << " while loading DLL " << libname << " via LoadLibraryExA: ";
addLastError(s);
THROW_EXCEPTION(DYNAMIC_LIBRARY_FAILURE, s.str());
}

THROW_EXCEPTION(DYNAMIC_LIBRARY_FAILURE, s.str());

#elif defined(HAVE_DLFCN_H)
// ToDo switch to RTLD_LAZY for performance?
libhandle = dlopen(libname.c_str(), RTLD_NOW);
Expand Down

0 comments on commit 43a6341

Please sign in to comment.