dynapi: Minor cleanups to library loading code.

This commit is contained in:
Ryan C. Gordon
2026-03-18 13:12:56 -04:00
parent 6b060435e3
commit b0cf826227

View File

@@ -448,27 +448,28 @@ Sint32 SDL_DYNAPI_entry(Uint32 apiver, void *table, Uint32 tablesize)
} }
#endif #endif
// The handle to the other SDL library, loaded with SDL_DYNAMIC_API_ENVVAR
#if defined(WIN32) || defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN)
static HMODULE lib = NULL;
#elif defined(SDL_PLATFORM_UNIX) || defined(SDL_PLATFORM_APPLE) || defined(SDL_PLATFORM_HAIKU)
static void *lib = NULL;
#else
#error Please define your platform.
#endif
// Obviously we can't use SDL_LoadObject() to load SDL. :) // Obviously we can't use SDL_LoadObject() to load SDL. :)
// Also obviously, we never close the loaded library. // Also obviously, we never close the loaded library, once we accept it.
#if defined(WIN32) || defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN) #if defined(WIN32) || defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN)
static HMODULE sdlapi_lib = NULL; // The handle to the other SDL library, loaded with SDL_DYNAMIC_API_ENVVAR
static SDL_INLINE void unload_sdlapi_library(void)
{
if (sdlapi_lib) {
FreeLibrary(sdlapi_lib);
sdlapi_lib = NULL;
}
}
static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym) static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym)
{ {
lib = LoadLibraryA(fname); sdlapi_lib = LoadLibraryA(fname);
void *result = NULL; void *result = NULL;
if (lib) { if (sdlapi_lib) {
result = (void *) GetProcAddress(lib, sym); result = (void *) GetProcAddress(sdlapi_lib, sym);
if (!result) { if (!result) {
FreeLibrary(lib); unload_sdlapi_library();
lib = NULL;
} }
} }
return result; return result;
@@ -476,19 +477,31 @@ static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym)
#elif defined(SDL_PLATFORM_UNIX) || defined(SDL_PLATFORM_APPLE) || defined(SDL_PLATFORM_HAIKU) #elif defined(SDL_PLATFORM_UNIX) || defined(SDL_PLATFORM_APPLE) || defined(SDL_PLATFORM_HAIKU)
#include <dlfcn.h> #include <dlfcn.h>
static void *sdlapi_lib = NULL; // The handle to the other SDL library, loaded with SDL_DYNAMIC_API_ENVVAR
static SDL_INLINE void unload_sdlapi_library(void)
{
if (sdlapi_lib) {
dlclose(sdlapi_lib);
sdlapi_lib = NULL;
}
}
static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym) static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym)
{ {
lib = dlopen(fname, RTLD_NOW | RTLD_LOCAL); sdlapi_lib = dlopen(fname, RTLD_NOW | RTLD_LOCAL);
void *result = NULL; void *result = NULL;
if (lib) { if (sdlapi_lib) {
result = dlsym(lib, sym); result = dlsym(sdlapi_lib, sym);
if (!result) { if (!result) {
dlclose(lib); unload_sdlapi_library();
lib = NULL;
} }
} }
return result; return result;
} }
#else
#error Please define your platform.
#endif #endif
static void dynapi_warn(const char *msg) static void dynapi_warn(const char *msg)
@@ -557,14 +570,8 @@ static void SDL_InitDynamicAPILocked(void)
if (entry(SDL_DYNAPI_VERSION, &jump_table, sizeof(jump_table)) < 0) { if (entry(SDL_DYNAPI_VERSION, &jump_table, sizeof(jump_table)) < 0) {
dynapi_warn("Couldn't override SDL library. Using a newer SDL build might help. Please fix or remove the " SDL_DYNAMIC_API_ENVVAR " environment variable. Using the default SDL."); dynapi_warn("Couldn't override SDL library. Using a newer SDL build might help. Please fix or remove the " SDL_DYNAMIC_API_ENVVAR " environment variable. Using the default SDL.");
// unload the other SDL library // unload the failed SDL library
#if defined(WIN32) || defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN) unload_sdlapi_library();
FreeLibrary(lib);
lib = NULL;
#elif defined(SDL_PLATFORM_UNIX) || defined(SDL_PLATFORM_APPLE) || defined(SDL_PLATFORM_HAIKU)
dlclose(lib);
lib = NULL;
#endif
// Just fill in the function pointers from this library, later. // Just fill in the function pointers from this library, later.
} else { } else {