You say this is 2 separate problems, but I don't see it that way, because even "largely-static data" can have a "complex, richly-typed, and dynamic [..] in-memory representation" (forgive the quote-juggling). If I have a 3D model, with vertices/indices/materials/shaders/textures/animations, some of which are obviously composed of the others, others merely associating with the others, that's all static data (as far as running the game is concerned), but is going to have a relatively complex in-memory representation. No?
I think what I've found interesting is that some developers have exactly that - fairly complex objects in memory - that they're reading in via fread and some fancy pointer twisting. I guess that is probably facilitated by something in the build process ensuring these objects are all contiguous - or just writing them out in such a way and going back to patch up pointers later. Since I've never worked on the build pipeline I've not been exposed to these methods before; it's only after hitting a couple of deserialisation bugs that I realised this sort of thing was common.
Let me steer this towards a practical question then; for those using these low-overhead methods, what are you doing to ensure that the layout of data is exactly what you expect - endianness, platform dependent types, 32bit vs 64bit, alignment (inc. SIMD requirements), padding, etc?