Created
March 30, 2021 11:46
-
-
Save rexim/1bff2d3da1459fa8c5278f058613fa8f to your computer and use it in GitHub Desktop.
Simple dl example using SDL2 on Linux
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// $ 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