问题
I have a dynamic library which I load using dlopen()
and then unload using dlclose()
;
If I dont include any objective c code dlopen()
needs one dlclose()
call which is expected behavior. But when I include any objective c code to target, I have problem that I need to do two dlclose()
calls to the loaded library in order to unload.
Is this something expected behavior? How can I fix it?
回答1:
I realize that you are using dlopen
, not CFBundle
or NSBundle
. Nevertheless, the Code Loading Programming Topics manual says this:
In Cocoa applications, you should not use
CFBundle
routines to load and unload executable code, becauseCFBundle
does not natively support the Objective-C runtime.NSBundle
correctly loads Objective-C symbols into the runtime system, but there is no way to unload Cocoa bundles once loaded due to a runtime limitation.
and this:
Because of a limitation in the Objective-C runtime system,
NSBundle
cannot unload executable code.
This makes me suspect that when you load your library, it registers itself with the Objective-C runtime, and the runtime calls dlopen
on the library again (or somehow increases the library's reference count).
I searched the Objective-C runtime source code and found this:
// dylibs are not allowed to unload
// ...except those with image_info and nothing else (5359412)
if (result->mhdr->filetype == MH_DYLIB && _hasObjcContents(result)) {
dlopen(result->os.dl_info.dli_fname, RTLD_NOLOAD);
}
So yes, the Objective-C runtime is calling dlopen
on your library specifically to prevent it from being unloaded. If you cheat and call dlclose
twice, you should expect bad things to happen.
来源:https://stackoverflow.com/questions/8793099/unload-dynamic-library-needs-two-dlclose-calls