I am making a renderer as a hobby, one thing I thought to try is making the low levelAPI be dynamically swappable, i.e. you could have an opengl or vulkan backend and switch between the two without needing to recompile or even relaunch the application.
To achieve this I am making 2 binaries, one is the executable, the other is the rendering code.
Let's call them main
and rendering
. For this to work, there is a core header Core.hpp
that defines all the C like functions and message PODs that are used to pass information between main
and rendering
.
I have one issue, I need to create objects/class instances in rendering
. Due to a series of constraints these are C++ instead of C, which means they cannot easily pass the barrier between the 2 binaries.
Because these objects need to live for as long as the rendering code is available, my current approach to handling their memory is to allocate on the heap into global pointers that are deleted when the main
calls a deinit method. For example, the memory allocation object would be initialized like this
MemoryAllocHandler * mem_handler;
void Init()
{
mem_handler = new MemoryAllocHandler();
}
void deinit()
{
delete mem_handler;
}
This way I can expose a C like API that receives parameters and uses these objects to handle rendering (fro example allocating OpenGL buffers).
This works, but I hate it. If I was statically linking rather than dynamic linking, I would not allocate on the heap, I would allocate on the stack and return these objects, hold them in some structure initialized at the highest possible scope and rely on RAII idioms to have its memory freed.
For example:
MemoryAllocHandler Init()
{
return MemoryAllocHandler();
}
Is there a way I could do something like the above while still dynamically linking? Take into account the prior is A C++ function with a C++ struct return type so name mangling is not just present but necessary.