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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With