it's quite simple actually.. all you do is identifying the minimum "graphics concepts" that your game need without calling the native API and then "wrap" these behind classes that expose the functionality you need.
So, for example, you might end up with a VertexBuffer class that wraps whatever calls to the API you need to manage vertex buffers.
At that point it's all about deciding how to implement the 2 versions... you can have the implementations deriving from a common interface.. ie. IVertexBuffer and residing in a dll.. or you can have static libs.
IMO, most of the times, there is no need for the dll approach.. when you build for a target system you just link the most appropriate static lib and call it a day.