2012-01-09 6 views
7

Tengo una biblioteca dinámica que cargo usando dlopen() y luego descargo usando dlclose();descargar la biblioteca dinámica necesita dos llamadas dlclose()?

Si no incluyo ningún código c objetivo dlopen() necesita una llamada dlclose(), que es el comportamiento esperado. Pero cuando incluyo un código de objetivo C en el destino, tengo el problema de que necesito hacer dos llamadas dlclose() a la biblioteca cargada para descargar.

¿Es esto algo comportamiento esperado? ¿Cómo puedo arreglarlo?

+0

¿Estás seguro de que tu biblioteca no está 'dlopen'-ed dos veces de forma oculta? O tal vez un error, por ejemplo, fuga de memoria: ¿está sobrescribiendo la memoria cerca del controlador 'dlopen'-ed? –

+0

dlopen mantiene un recuento de referencias en el identificador de la biblioteca. Si dlopen se realizó dos veces, se requerirán dos dlclose() para descargar la biblioteca. ¿Es posible que se requiera la biblioteca dinámica si incluye el código obj-C? En ese caso, el primer dlopen se puede hacer cuando ejecuta su programa – Finslicer

+0

Sí, estoy seguro de que no está dlopeado dos veces. Puede probar un programa simple en main con dlopen seguido de dlclose con la biblioteca dinámica que tiene el código objetivo c. – MacGeek

Respuesta

26

Me doy cuenta de que está utilizando dlopen, no CFBundle o NSBundle. Sin embargo, el manual Code Loading Programming Topics dice esto:

En aplicaciones Cocoa, no se debe utilizar CFBundle rutinas para cargar y descargar el código ejecutable, porque CFBundle no soporta de forma nativa el tiempo de ejecución de Objective-C. NSBundle carga correctamente símbolos de Objective-C en el sistema de tiempo de ejecución, pero no hay forma de descargar los paquetes de Cacao una vez cargados debido a una limitación de tiempo de ejecución.

y esto:

Debido a una limitación en el sistema de tiempo de ejecución de Objective-C, NSBundle no puede descargar código ejecutable.

Esto me hace sospechar que cuando se carga la biblioteca, se registra con el tiempo de ejecución de Objective-C, y el tiempo de ejecución llama dlopen en la biblioteca de nuevo (o de alguna manera incrementa el contador de referencia de la biblioteca).

busqué el código fuente en tiempo de ejecución de Objective-C y se encontró 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); 
} 

Así que sí, el tiempo de ejecución de Objective-C está llamando dlopen en su biblioteca específicamente para evitar que sea descargado. Si hace trampa y llama al dlclose dos veces, debe esperar que sucedan cosas malas.

+0

+1 excelente respuesta! – Till

Cuestiones relacionadas