floooh / sokol

minimal cross-platform standalone C headers
https://floooh.github.io/sokol-html5
zlib License
7.06k stars 494 forks source link

sokol_dyn: proof-of-concept of a DLL loader-wrapper #466

Open code-disaster opened 3 years ago

code-disaster commented 3 years ago

So, I gave some of the idea(s) discussed in #338 a try, and this is what I got so far:

sokol_dyn.h noentry-dll-loader-sapp.c

This loads sokol_app/_gfx/_glue functions from (the already existing) sokol-dll.dll. The sample is a clone of noentry-dll-sapp, so you can compare how few lines I had to change from a user's point of view.

After a few initial struggles, I'm pretty happy with how not-intrusive-at-all this turned out. Yay for C/C++ preprocessor macro magic!

I don't think it's a good idea to move all sokol libraries (plus their dependencies, like Dear Imgui) into DLLs. One remaining road block are embedded shader sources. Right now, they are conditionally compiled based on the selected backend. What I did with sokol_imgui as an experiment looks like this:

sokol_dyn_and_imgui

So, in the implementation unit, I can define multiple backends to have shaders embedded for, and at runtime, the one to use is selected based on sg_query_backend().

floooh commented 3 years ago

Apologies for looking at this so late.

Wow, this is really much less code than I expected.

Right now, they are conditionally compiled based on the selected backend...

Hmm ok. I think the best solution would be to select a strategy through a config-define. The "dynamic" version via sg_query_backend() has the disadvantage that all shader sources must be contained in the executable.

code-disaster commented 3 years ago

My current test project does both, so the "client-side" implementation looks like this:

#define SOKOL_NO_ENTRY

/* no impl, loaded from DLL */

#include <sokol_app.h>
#include <sokol_gfx.h>
#include <sokol_glue.h>

/* impl part starts here */

#define SOKOL_IMPL

#include <util/sokol_dyn.h>

#include <sokol_time.h>

/* we want to load from sokol-d3d.dll or sokol-gl.dll, so embed shaders for both */

#define SOKOL_D3D11
#define SOKOL_GLCORE33

#include <imgui.h>
#include <util/sokol_imgui.h>

The embedded shader code is #ifdef'd so that (only) these two versions are included, and the sg_query_backend() is used to decide which one to use at runtime.