Las bibliotecas de envoltura (o envoltorios de bibliotecas ) consisten en una fina capa de código (una " capa de corrección ") que traduce la interfaz existente de una biblioteca a una interfaz compatible. Esto se hace por varias razones:
Las bibliotecas de envoltura se pueden implementar utilizando los patrones de diseño adaptador , fachada y, en menor medida, proxy .
La forma específica en que se implementa una biblioteca contenedora es muy específica del entorno en el que se escribe y de los escenarios a los que pretende dirigirse. Esto es especialmente cierto en el caso en que la interoperabilidad entre lenguajes y entornos de ejecución es un factor a tener en cuenta.
A continuación se ofrece una ilustración general de una implementación de biblioteca de contenedor común. En este ejemplo, una interfaz de C++ actúa como un "contenedor" alrededor de una interfaz de C.
int pthread_mutex_init ( pthread_mutex_t * mutex , pthread_mutexattr_t * attr ) ; int pthread_mutex_destroy ( pthread_mutex_t * mutex ); int pthread_mutex_lock ( pthread_mutex_t * mutex ); int pthread_mutex_unlock ( pthread_mutex_t * mutex );
clase Mutex { pthread_mutex_t mutex ; público : Mutex () { pthread_mutex_init ( & mutex , 0 ); } ~ Mutex () { pthread_mutex_destroy ( & mutex ); } privado : clase amiga Bloqueo ; bloqueo vacío () { pthread_mutex_lock ( & mutex ); } anular desbloqueo () { pthread_mutex_unlock ( & mutex ); } }; clase Lock { privado : Mutex y mutex ; público : Bloquear ( Mutex & mutex ) : mutex { mutex } { mutex .lock () ; } ~ Bloquear () { mutex.unlock () ; } } ;
La interfaz C original puede considerarse propensa a errores, en particular en el caso en que los usuarios de la biblioteca olvidan desbloquear un mutex ya bloqueado. La nueva interfaz utiliza de manera efectiva la adquisición de recursos en la inicialización (RAII) en las nuevas clases Mutex y Lock para garantizar que los Mutex se desbloqueen finalmente y que los objetos pthread_mutex_t se liberen automáticamente.
El código anterior imita de cerca la implementación de boost::scoped_lock y boost::mutex, que son parte de la biblioteca boost::thread.
Existen algunas bibliotecas contenedoras que actúan como puente entre una aplicación cliente y una biblioteca escrita con una tecnología incompatible. Por ejemplo, una aplicación Java puede necesitar ejecutar una llamada al sistema . Sin embargo, las llamadas al sistema suelen exponerse como funciones de biblioteca C. Para resolver este problema, Java implementa bibliotecas contenedoras que hacen que estas llamadas al sistema se puedan llamar desde una aplicación Java.
Para lograr esto, lenguajes como Java proporcionan un mecanismo llamado interfaz de función externa que lo hace posible. Algunos ejemplos de estos mecanismos incluyen:
Algunos ejemplos de bibliotecas wrapper existentes: