Librerie Una libreria è una collezione di funzioni (classi, variabili) usata per sviluppare applicazioni. Le funzioni (classi, variabili) contenute in una libreria si dicono da questa esportate. L'uso delle librerie permette di o condividere codice e dati tra diverse applicazioni o riutilizzare del codice già scritto (e compilato) o organizzare un programma in modo modulare e omogeneo Le libreria possono essere a collegamento statico o dinamico Laboratorio di Informatica Antonio Monteleone 28
Librerie a collegamento statico Una libreria statica consiste in una collezione di funzioni (variabili, classi). E compito del linker collegare tali elementi nell'applicazione generata (eseguibile o libreria) (ne divengono parte). Tipiche estensioni delle librerie statiche Windows:.lib UNIX:.a (corrisponde a un archivio) Opzioni di link in Dev-C++ (GCC) o -llibrary o semplicemente library o -L library_folder_path Il linker risolve i riferimenti esterni cercando tra le librerie passategli in input nell'ordine dato Laboratorio di Informatica Antonio Monteleone 29
Librerie a collegamento dinamico (1) Nel collegamento dinamico le componenti di una libreria sono caricate nel programma a tempo di esecuzione piuttosto che essere collegate dal linker. Esse restano separate dell eseguibile e contenute in un file separato Il linker registra nell eseguibile l elenco delle funzioni (classi) da collegare dinamicamente il nome della libreria che la contiene e il numero ordinale della funzione all interno della libreria Tipiche estensioni delle librerie a collegamento dinamico Windows:.dll (dynamic link library) UNIX:.so (shared object) Laboratorio di Informatica Antonio Monteleone 30
Librerie a collegamento dinamico (2) A tempo di esecuzione la libreria dinamica viene ricercata (quando e dove) con un meccanismo tipico del sistema operativo. Windows: all avvio del programma (quando) prima nella directory dell eseguibile e dopo nelle directory presenti nella variabile d ambiente PATH UNIX: quando è invocata una funzione in essa contenuta nelle directory presenti nella variabile d ambiente LD_LIBRARY_PATH Quando un eseguibile necessita di una libreria dinamica e questa non è raggiungibile il loader segnala l errore e non prosegue l esecuzione del programma. Laboratorio di Informatica Antonio Monteleone 31
Librerie a collegamento dinamico (3) Vantaggi delle librerie a collegamento dinamico o Condivisione tra diverse applicazioni o Aggiornamento - Possono essere aggiornate (patches) senza dover ricompilare l applicazione, a patto che l interfaccia delle funzioni (prototipi) e delle classi (dichiarazioni) esportate non sia stata modificata o Caricamento on Demand delle funzioni (solo quando servono) Utilizzato per implementare il meccanismo dei plugin Laboratorio di Informatica Antonio Monteleone 32
Librerie a collegamento dinamico (4) Come caricare dinamicamente (on demand) una funzione esportata da una libreria dinamica 1. Si ottiene un handle alla libreria attraverso una funzione di sistema LoadLibrary sotto Windows dlopen per i sistemi Unix-like (Linux, Mac-OsX) 2. Si chiede al sistema un puntatore alla funzione da caricare, specificando l handle alla libreria e il nome della funzione GetProcAddress sotto Windows dlsym per i sistemi Unix-like 3. Si dereferenzia il puntatore a funzione per chiamare la funzione desiderata Laboratorio di Informatica Antonio Monteleone 33
Come creare una dll in DevC++ (1) DevC++ fornisce la possibilità di creare uno scheletro di progetto dll 1. creo un nuovo\progetto\ di tipo "DLL 2. DEV C++ crea per noi ( lo scheletro ) un file di progetto.dev (avente il nome dato al progetto) un file header (dll.h) con la dichiarazione di una classe DllClass esportata dalla dll un file c++ (dllmain.cpp) con uno scheletro di implementazione della classe DllClass e un entry-point alla dll dato dalla funzione DllMain definisce la macro BUILDING_DLL mediante l aggiunta del parametro di compilazione -DBUILDING_DLL=1 (Project Options Parameters) Alla fine della generazione della dll verrà creato anche un file.lib e un file.a Se non si vuole usare il caricamento on-demand il file di libreria (.lib o.a) va linkato al progetto che usa la libreria Laboratorio di Informatica Antonio Monteleone 34
Come creare una dll in DevC++ (2) // dll.h #ifndef _DLL_H_ #define _DLL_H_ #if BUILDING_DLL # define DLLIMPORT declspec (dllexport) #else /* Not BUILDING_DLL */ # define DLLIMPORT declspec (dllimport) #endif /* Not BUILDING_DLL */ class DLLIMPORT DllClass { public: DllClass(); virtual ~DllClass(void); private: }; #endif /* _DLL_H_ */ Laboratorio di Informatica Antonio Monteleone 35
Come creare una dll in DevC++ (3) // dllmain.cpp #include "dll.h" #include <windows.h> DllClass::DllClass(){} DllClass::~DllClass (){} BOOL APIENTRY DllMain ( HINSTANCE hinst, DWORD reason, LPVOID reserved) { switch (reason) { case DLL_PROCESS_ATTACH: break; case DLL_PROCESS_DETACH: break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; } return TRUE; } Laboratorio di Informatica Antonio Monteleone 36
Esempio di caricamento on demand (1) class PluginInfo { /*...*/}; typedef const PluginInfo *lipluginmain(); static const char *PluginMainName = "lipluginmain"; const PluginInfo *getplugininfo(const string &filepath) { const PluginInfo *info = 0; #ifdef WIN32 HINSTANCE handle = LoadLibrary(filepath.c_str()); #else void *handle = dlopen(filepath.c_str(), RTLD_LAZY); #endif // continua Laboratorio di Informatica Antonio Monteleone 37
Esempio di caricamento on demand (2) // continua getplugininfo if (!handle) { // gestire l'errore nel caricamento } else { #ifdef WIN32 lipluginmain *pluginentrypoint = (lipluginmain *) GetProcAddress(handle, PluginMainName); #else lipluginmain *pluginentrypoint = (lipluginmain *) dlsym(handle, PluginMainName); #endif if (pluginentrypoint) info = pluginentrypoint(); } return info; } // getplugininfo Laboratorio di Informatica Antonio Monteleone 38
Una libreria di funzioni matematiche (1) Realizzare una libreria di funzioni matematiche mymath nelle versioni a collegamento statico e dinamico Due (quattro) configurazioni di progetto Libreria statica (.a,.lib) (debug + release) Libreria dinamica (.so,.dll) (debug + release) Valutazione di polinomi Funzioni combinatorie fattoriale, coefficiente binomiale Funzioni statistiche (su array di double) Minimo, massimo, somma, media, varianza, deviazione standard, media geometrica, mediana, media geometrica, media armonica, autocorrelazione Laboratorio di Informatica Antonio Monteleone 39
Una libreria di funzioni matematiche (2) #if defined( WIN32 WIN64) #define MYMATH_EXPORT declspec(dllexport) #define MYMATH_IMPORT declspec(dllimport) #else #if defined( linux ) #define MYMATH_EXPORT #define MYMATH_IMPORT #else #error - unsupported platform. #endif #endif Laboratorio di Informatica Antonio Monteleone 40
Una libreria di funzioni matematiche (3) #undef MYMATH_API #if defined(mymath_static_lib ) #define MYMATH_API #else #if defined(mymath_dll_build ) #define MYMATH_API MYMATH_EXPORT #else #define MYMATH_API MYMATH_IMPORT #endif #endif Laboratorio di Informatica Antonio Monteleone 41
Una libreria di funzioni matematiche (4) File di inclusione mymath.h MYMATH_API double get_mean( double a[], int size); Per la libreria statica va definito MYMATH_STATIC_LIB (sia nel progetto di implementazione che in quello che usa la libreria) Per la libreria dinamica va definito WIN32 o WIN64 o linux a seconda della piattaforma Laboratorio di Informatica Antonio Monteleone 42