carb::extras::loadLibrary
Defined in carb/extras/Library.h
-
inline LibraryHandle carb::extras::loadLibrary(const char *libraryName, LibraryFlags flags = 0)
Attempts to load a named library into the calling process.
This attempts to dynamically load a named library into the calling process. If the library is already loaded, the reference count of the library is increased and a handle to it is returned. If the library was not already loaded, it is dynamically loaded and a handle to it is returned; its reference count will be one. Each call to this function should be balanced by a call to unloadLibrary() when the library is no longer needed.
Libraries that were loaded as part of the process’s dependencies list will be ‘pinned’ and their reference count will not be changed by attempting to load them. It is still safe to unloadLibrary() on handles for those libraries.
- Windows
This function calls LoadLibraryEx with
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
andLOAD_LIBRARY_SEARCH_DEFAULT_DIRS
to load libraries. If this fails, the default search path is instead used. IfERROR_FILENAME_EXCED_RANGE
is returned, theLoadLibraryEx
call is repeated with the filepath preceded with a prefix to disable string parsing. If the module or a dependent module is not found,GetLastError()
typically reportsERROR_MOD_NOT_FOUND
. In order to determine which DLL library is missing there are a few options:Enable Show Loader Snaps with the gflags tool, which is available with Debugging Tools for Windows. Running the process in a debugger or with access to debug output will then show log messages from the Windows loader.
The same debug output can be enabled by setting the 32-bit value at
ntdll.dll!LdrpDebugFlags
to0x1
. This value must be accessed in a debugger with symbols for ntdll.dll.Alternately using a modern Dependencies tool will reveal missing dependencies for a library without a debugger, although it may not show the actual error that led to
loadLibrary
failing.
- Linux
This function calls dlopen with the
RTLD_LAZY
flag (orRTLD_NOW
if fLibFlagNow is specified). If fLibFlagDeepBind is specified,RTLD_DEEPBIND
is also used. It is possible for the underlyingdlopen()
call to succeed without a dependent library able to load. In this case, the dynamic loader destroys the link map, so symbol lookup on the module will fail. This condition is detected and treated as an error condition. To have dynamic loader debug output displayed, use the LD_DEBUG environment variable set to a value such asfiles
,libs
orall
. Typically the output is printed to stdout, but theLD_DEBUG_OUTPUT
can be set to the name of a file to instead log to the file. The ldd command-line tool can be used to print the dependent libraries required by an executable or library.- MacOS
This function calls
dlopen
with theRTLD_LAZY
flag (orRTLD_NOW
if fLibFlagNow is specified). To have the dynamic loader debug output displayed, use the DYLD_PRINT_LIBRARIES environment variable. Theotool
command-line tool with the-L
option will print out the dependent libraries required by an executable or library.- MacOS
If the requested library name is
nullptr
, the expectation from the caller is that the handle to the process’ main executable image will be returned. Unfortunately on MacOS, theRTLD_DEFAULT
symbol is returned instead as a pseudo-handle to the main executable module. This is valid to pass to other functions such as getLibrarySymbol() and getLibraryFilenameByHandle() however.
Note
A library may fail to load because of a dependent library, but the error message may seem like the requested library is causing the failure.
- Parameters
libraryName – [in] The name of the library to attempt to load. This may be either a relative or absolute path name. This should be a UTF-8 encoded path. If the fLibFlagMakeFullLibName flag is used, the library name may omit any platform specific prefix or file extension. The appropriate platform specific name will be generated internally using createLibraryNameForModule(). If
nullptr
is provided, the executable module is retrieved instead. On Windows this handle need not be closed with unloadLibrary() as it does not increment the reference count, but on MacOSX and Linux it increments the reference count and should therefore be passed to unloadLibrary().flags – [in] Flags to control the behavior of the operation. This defaults to 0.
- Returns
A handle to the library if it was already loaded in the process. This handle should be cleaned up by unloadLibrary() when it is no longer necessary.
nullptr
is returned if the library could not be found, or loading fails for some reason (use getLastLoadLibraryError()).