卸载动态库需要两个dlclose()调用?
我有一个动态库,我加载使用dlopen()
,然后卸载使用dlclose()
;卸载动态库需要两个dlclose()调用?
如果我不包括任何客观的c代码dlopen()
需要一个dlclose()
调用这是预期的行为。但是,当我包含任何目标C代码目标时,我有问题,我需要执行两个dlclose()
调用加载的库来卸载。
这是一些预期的行为?我该如何解决它?
我知道您使用的是dlopen
,而不是CFBundle
或NSBundle
。尽管如此,Code Loading Programming Topics手册这样说:
在Cocoa应用程序,你不应该使用
CFBundle
程序加载和卸载可执行代码,因为CFBundle
本身不支持Objective-C的运行时间。NSBundle
将Objective-C符号正确加载到运行时系统中,但由于运行时限制,无法卸载一次加载的可可包。
和此:
因为在Objective-C运行系统中的限制,
NSBundle
不能卸载可执行代码。
这让我怀疑,当你到您的书架,它本身注册Objective-C运行,并且运行时调用dlopen
在图书馆试(或以某种方式增加库的引用计数)。
我搜索了Objective-C运行的源代码,发现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);
}
所以,是的,Objective-C的运行时在你的库调用dlopen
明确,以防止它被卸载。如果你欺骗并且拨打dlclose
两次,你应该预料会发生不好的事情。
+1优秀的答案! – Till 2012-01-09 19:13:22
你确定你的图书馆不是以隐藏的方式进行两次“dlopen”编辑吗?或者可能是一个错误 - 例如内存泄漏 - 覆盖“dlopen”手柄附近的内存? – 2012-01-09 18:13:10
dlopen保持库处理的引用计数。如果dlopen执行了两次,则需要两个dlclose()来卸载该库。如果包含obj-C代码,是否需要动态库?在这种情况下,第一个dlopen可能会在您运行程序时完成 – Finslicer 2012-01-09 18:13:53
是的,我相信它不会两次跳过。你可以尝试一个简单的程序,主要用dlopen,然后用带有目标c代码的动态库的dlclose。 – MacGeek 2012-01-09 18:26:54