I hear about D often on HN but I never see it being used in the wild so to speak. When I looked at it, it seemed, like C++, a hodgepodge of features built up over time rather than being a more deliberately focused language.
I hate to compare and contrast but Rust comes to mind as one of the latter, probably because it has a somewhat more intensive and extensive RFC process for adding new features.
D has made its mistakes (there's no way to evolve a language over 20 years and not make a mistake here and there), but we also have a deprecation process to remove them.
This is even more impressive than LuaJIT's FFI in my opinion, which I previously thought was state of the art. You basically pass in a preprocessed header, and LuaJIT does the rest.
All this to say, I feel that any FFI that requires you to manually write bindings is rubbish.
We lived with manual bindings to interface with C for years. Building in direct support for C itself is a huge leap forward in usability. In several ways it's even better than C++'s support for C.
How does it deal with the macro-in-macro-in-macro soup that a non trivial amount of headers are? c2nim does a decent job but struggles with some of those types. gcc -E on the header works around it, so I wonder if c2nim could be made to operate similarly to what you’re describing.