2012-01-09 8 views
7

Ho una libreria dinamica che carico utilizzando dlopen() e quindi scarico utilizzando dlclose();scarica libreria dinamica ha bisogno di due chiamate dlclose()?

Se non includo alcun codice obiettivo ogg dlopen() necessita di una chiamata dlclose() quale comportamento previsto. Ma quando includo qualsiasi codice obiettivo c verso il target, ho il problema che ho bisogno di fare due chiamate dlclose() alla libreria caricata per scaricare.

È qualcosa che si aspetta un comportamento? Come posso ripararlo?

+0

Sei sicuro che la tua libreria non 'dlopen'ed due volte in un modo nascosto? O forse un bug -e.g. perdita di memoria - sovrascrive la memoria vicino all'handle 'dlopen'ed? –

+0

dlopen mantiene un conteggio dei riferimenti sull'handle della libreria. Se dlopen è stato eseguito due volte, sarà necessario due dlclose() per scaricare la libreria. È possibile che la libreria dinamica sia necessaria se si include il codice obj-C? Nel qual caso il primo dlopen può essere fatto quando si esegue il programma – Finslicer

+0

Sì, sono sicuro che non è stato aperto due volte. Puoi provare un programma semplice in main con dlopen seguito da dlclose con una libreria dinamica che ha codice c oggettivo. – MacGeek

risposta

26

Mi rendo conto che si sta usando dlopen, non CFBundle o NSBundle. Tuttavia, il manuale di Code Loading Programming Topics dice questo:

In applicazioni Cocoa, non si deve usare CFBundle routine per caricare e scaricare il codice eseguibile, perché CFBundle non supporta nativamente il runtime Objective-C. NSBundle carica correttamente i simboli Objective-C nel sistema di runtime, ma non è possibile scaricare i pacchetti Cocoa una volta caricati a causa di una limitazione di runtime.

e questo:

causa di una limitazione nel sistema runtime Objective-C, NSBundle non può scaricare codice eseguibile.

Questo mi fa sospettare che quando si carica la libreria, si registra con il runtime Objective-C, e il runtime chiama dlopen sulla libreria di nuovo (o in qualche modo aumenta conteggio dei riferimenti della biblioteca).

ho cercato il codice sorgente di runtime Objective-C e trovato 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); 
} 

Quindi sì, il runtime Objective-C sta chiamando dlopen sulla tua libreria appositamente per evitare che venga scaricato. Se imbroglia e chiami il numero dlclose due volte, dovresti aspettarti che accadano cose brutte.

+0

+1 ottima risposta! – Till

Problemi correlati