我有一個動態庫,我加載使用dlopen()
,然後卸載使用dlclose()
;卸載動態庫需要兩個dlclose()調用?
如果我不包括任何客觀的c代碼dlopen()
需要一個dlclose()
調用這是預期的行爲。但是,當我包含任何目標C代碼目標時,我有問題,我需要執行兩個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