Using SDL to dynamically load itself?

Issue: I would like to dynamically load the SDL library and its functions at runtime, like you can usually do with other dynamic libraries. However, I obviously can’t use SDL to load itself without some sort of bootstrap problem.

In order to do what I wish, I think I have three options:

1. Attempt to modify the SDL source to extricate the SDL_loadso functionality into a completely separate source header, and include that in my project.

2. Simply write my own equivalent loadso layer.

3. Find an equivalent cross-platform loadso library.

From what I have found so far, there are no libraries that have both the functionality of SDL_loadso and maintain the same level of cross-platform support.

Am I missing something obvious, or does anyone have any relevant tips/experience to proceed with this?

Thanks for your time.

Why can’t you load SDL dynamically like you do with other libraries? Obviously the dynamic loading code looks different depending on your platform but there is no reason why It shouldn’t work. For example on a Linux system:

#include <dlfcn.h>
#include <stdio.h>
#include <SDL2/SDL.h>

int main() {
    void *lib = dlopen("libSDL2.so", RTLD_NOW | RTLD_LOCAL);
    if (!lib) {
        printf("Couldn't load SDL: %s\n", dlerror());
        return -1;
    }
    typeof(SDL_Init) *pSDL_Init = dlsym(lib, "SDL_Init");
    typeof(SDL_Quit) *pSDL_Quit = dlsym(lib, "SDL_Quit");
    typeof(SDL_ShowSimpleMessageBox) *pSDL_ShowSimpleMessageBox = dlsym(lib, "SDL_ShowSimpleMessageBox");
    typeof(SDL_GetSystemRAM) *pSDL_GetSystemRAM = dlsym(lib, "SDL_GetSystemRAM");
    if (!pSDL_Init || !pSDL_Quit || !SDL_ShowSimpleMessageBox || !pSDL_GetSystemRAM) {
        printf("Couldn't load one or more of the symbos\n");
        return -1;
    }

    pSDL_Init(SDL_INIT_EVERYTHING);

    char buffer[128];
    snprintf(buffer, 128, "It's fine to dynamically load SDL.\nYour system has %i MB of RAM.", pSDL_GetSystemRAM());
    pSDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Dynamic loading", buffer, NULL);

    pSDL_Quit();
    dlclose(lib);

    return 0;
}

image

If you absolutely don’t want to mess with platform specific dynload functions or function pointers manually at all, you could modify the SDL dynapi to your needs, not compiling any of the other sources and rely on the SDL dynamic api to always load the functionality. I would refrain from doing that though.

Personally I use my own or node-ffi-napi/win32-dlfcn.cc at master · node-ffi-napi/node-ffi-napi · GitHub (public domain) for proprietary platforms and Windows. Rest of the world should have <dlfcn.h> almost everywhere.

Unless I’ve misunderstood your code, it doesn’t implement what is (arguably) the most useful feature of dlsym(): the ability to pass the value RTLD_DEFAULT (-1) as the library handle. This causes it to search all the available libraries, without you having to open each one individually. I rely on this in my application, so in Windows I use this equivalent:

void *dlsym (void *handle, const char *symbol)
{
	void *procaddr;
	HMODULE modules[100];
	long unsigned int i, needed;
	K32EnumProcessModules((HANDLE)-1, modules, sizeof (modules), &needed);
	for (i = 0; i < needed / sizeof (HMODULE); i++)
	    {
		procaddr = GetProcAddress(modules[i], symbol);
		if (procaddr != NULL) break;
	    }
	return procaddr;
}

Yup. SDL_LoadFunction has same limitation and some platforms simply lack RTLD_DEFAULT to avoid namespace pollution that could be happen different versions of shared library in a same process.

Yeah, when I said that I can’t use SDL to load itself, I meant I can’t load SDL using its own functions (i.e. SDL_LoadFunction, SDL_LoadObject). I was just asking if I was missing something obvious that would allow me to do that. But it looks like there isn’t. So I’ll just have to use/write an external library that provides the same cross-platform dlopen functionality to load SDL.

Thanks for the help.