Skip to content

Instantly share code, notes, and snippets.

@rexim
Created March 30, 2021 11:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rexim/1bff2d3da1459fa8c5278f058613fa8f to your computer and use it in GitHub Desktop.
Save rexim/1bff2d3da1459fa8c5278f058613fa8f to your computer and use it in GitHub Desktop.
Simple dl example using SDL2 on Linux
// $ cc -o main main.c -ldl
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <dlfcn.h>
#define SDL_LIBRARY_NAME "libSDL2-2.0.so"
#define SDL_INIT_VIDEO 0x00000020u
#define SDL_WINDOW_RESIZABLE 0x00000020
#define SDL_RENDERER_ACCELERATED 0x00000002
#define SDL_QUIT 0x100
typedef void SDL_Window;
typedef void SDL_Renderer;
typedef union SDL_Event {
uint32_t type;
uint8_t padding[56];
} SDL_Event;
int (*SDL_Init)(uint32_t flags) = NULL;
const char *(*SDL_GetError)(void) = NULL;
void (*SDL_Quit)(void) = NULL;
SDL_Window *(*SDL_CreateWindow)(const char *title,
int x, int y, int w,
int h, uint32_t flags) = NULL;
SDL_Renderer *(*SDL_CreateRenderer)(SDL_Window * window,
int index, uint32_t flags) = NULL;
int (*SDL_PollEvent)(SDL_Event *event) = NULL;
int (*SDL_SetRenderDrawColor)(SDL_Renderer* renderer, uint8_t r, uint8_t g, uint8_t b, uint8_t a) = NULL;
int (*SDL_RenderClear)(SDL_Renderer* renderer) = NULL;
void (*SDL_RenderPresent)(SDL_Renderer* renderer) = NULL;
void *load_symbol(void *handle, const char *name)
{
void *result = dlsym(handle, name);
if (result == NULL) {
fprintf(stderr, "ERROR: could not find symbol %s: %s\n",
name, dlerror());
exit(1);
}
printf("Successfully found symbol %s: %p\n", name, (void*)result);
return result;
}
void load_sdl(void *handle)
{
SDL_Init = load_symbol(handle, "SDL_Init");
SDL_GetError = load_symbol(handle, "SDL_GetError");
SDL_Quit = load_symbol(handle, "SDL_Quit");
SDL_CreateWindow = load_symbol(handle, "SDL_CreateWindow");
SDL_CreateRenderer = load_symbol(handle, "SDL_CreateRenderer");
SDL_PollEvent = load_symbol(handle, "SDL_PollEvent");
SDL_SetRenderDrawColor = load_symbol(handle, "SDL_SetRenderDrawColor");
SDL_RenderClear = load_symbol(handle, "SDL_RenderClear");
SDL_RenderPresent = load_symbol(handle, "SDL_RenderPresent");
}
int main(void)
{
void *sdl_lib = dlopen(SDL_LIBRARY_NAME, RTLD_LAZY);
if (sdl_lib == NULL) {
fprintf(stderr, "ERROR: could not load library `"SDL_LIBRARY_NAME"`: %s\n",
dlerror());
exit(1);
}
printf("Successfully loaded library `"SDL_LIBRARY_NAME"`\n");
load_sdl(sdl_lib);
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
fprintf(stderr, "ERROR: could not initialize SDL: %s\n", SDL_GetError());
exit(1);
}
SDL_Window *window = SDL_CreateWindow(
"Khello",
0, 0, 800,
600, SDL_WINDOW_RESIZABLE);
if (window == NULL) {
fprintf(stderr, "ERROR: could not create SDL window: %s\n", SDL_GetError());
exit(1);
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL) {
fprintf(stderr, "ERROR: could not create SDL renderer: %s\n", SDL_GetError());
exit(1);
}
int quit = 0;
while (!quit) {
SDL_Event event = {0};
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
quit = 1;
}
}
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
SDL_Quit();
if (dlclose(sdl_lib) != 0) {
fprintf(stderr, "ERROR: could not close library `"SDL_LIBRARY_NAME"`: %s\n",
dlerror());
exit(1);
}
printf("Successfully closed library `"SDL_LIBRARY_NAME"`\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment