卸载动态库需要两个dlclose()调用?

问题描述:

我有一个动态库,我加载使用dlopen(),然后卸载使用dlclose();卸载动态库需要两个dlclose()调用?

如果我不包括任何客观的c代码dlopen()需要一个dlclose()调用这是预期的行为。但是,当我包含任何目标C代码目标时,我有问题,我需要执行两个dlclose()调用加载的库来卸载。

这是一些预期的行为?我该如何解决它?

+0

你确定你的图书馆不是以隐藏的方式进行两次“dlopen”编辑吗?或者可能是一个错误 - 例如内存泄漏 - 覆盖“dlopen”手柄附近的内存? – 2012-01-09 18:13:10

+0

dlopen保持库处理的引用计数。如果dlopen执行了两次,则需要两个dlclose()来卸载该库。如果包含obj-C代码,是否需要动态库?在这种情况下,第一个dlopen可能会在您运行程序时完成 – Finslicer 2012-01-09 18:13:53

+0

是的,我相信它不会两次跳过。你可以尝试一个简单的程序,主要用dlopen,然后用带有目标c代码的动态库的dlclose。 – MacGeek 2012-01-09 18:26:54

我知道您使用的是dlopen,而不是CFBundleNSBundle。尽管如此,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两次,你应该预料会发生不好的事情。

+0

+1优秀的答案! – Till 2012-01-09 19:13:22