How would you write dlopen in portable C? Once you are loading code and calling into that its no longer portable C and on modern platforms you'd need at least something like mmap/mprotect to allow you to do that, which are POSIX but not C.
So you could write your own atexit, but maybe someone's got a version of atexit that cancels callbacks from unloaded libraries, or one that keeps them loaded if they have callbacks, or one that calls the callbacks immediately during dlclose.