Génie logiciel Librairies de liens dynamiques : DLL
Transcription
Génie logiciel Librairies de liens dynamiques : DLL
Génie logiciel Librairies de liens dynamiques : DLL SPE4 - ESI 1 DLL : Qu’est-ce que c’est ? DLL ⇔ Dynamic-Link Library ⇔ Librairies de Liens Dynamiques. Les DLL sont des fichiers (d’extension .dll) qui peuvent contenir des classes C++, des données globales, des fonctions compilées, des ressources. Les applications clientes exécutables peuvent charger des DLL et s’y rattacher en cours d’exécution, très rapidement, pour bénéficier de leurs caractéristiques. Lorsqu’elles en ont besoin, les applications clientes exécutables importent les fonctions des DLL. 2 Génie logiciel – DLL 1 Avantage des DLL : modularité Les DLL apportent la modularité à l’exécution. Les grosses applications clientes qui doivent être recompilées pour être testées, sont « éclatées » en modules plus réduits, testés plus rapidement individuellement. Exécutable ⇔ DLL 1 Exécutable DLL 2 DLL 3 3 Autre avantage des DLL Fourniture d’un code compilé aux clients Fichiers d’entêtes lisibles (déclarations) .h Fichiers dll compilés (code machine) .dll Protection du savoir faire Impossibilité de revenir au codage en langage évolué à partir d’un fichier en langage machine Rappel : Génération d’un exécutable Génie logiciel – DLL Compilation Edition de liens Exécutable 4 2 Import/Export des fonctions des DLL Une DLL contient une table des fonctions exportées qui contient : les noms symboliques des fonctions éventuellement, des entiers appelés nombres ordinaux associés à ces fonctions les adresses des fonctions dans la DLL Quand l’application cliente charge la DLL, elle utilise les noms symboliques ou les ordinaux. Le processus de liaison dynamique relie les appels du client aux adresses des fonctions dans la DLL. 5 Déclaration des fonctions des DLL Fonctions C Déclaration des fonctions exportées dans le code de la DLL __declspec(dllexport) int Fonction (int n); Déclaration des fonctions importées côté client __declspec(dllimport) int Fonction (int n); Fonctions C++ (noms décorés, cf fichier map du projet) Déclaration des fonctions exportées dans la DLL extern "C" __declspec(dllexport) int Fonction (int n); Déclaration des fonctions importées dans le client extern "C" __declspec(dllimport) int Fonction (int n); 6 Génie logiciel – DLL 3 Appel des fonctions des DLL Passage des paramètres des fonctions convention __cdecl (défaut) : la fonction appelante « dépile » les paramètres convention __stdcall (à préciser le cas échéant) : la fonction appelée « dépile » les paramètres Les déclarations d’importation ne suffisent pas à relier un client à une DLL. Il faut que : le projet client spécifie la librairie d’importation (lib) à l’éditeur de liens l’application cliente contiennent au moins un appel vers l’une des fonctions importées de la DLL 7 Fichiers requis pour utiliser une DLL Compilation de l’application cliente fichier .h de déclaration des fonctions de la DLL, utilisées dans l’application cliente (avec __declspec (dllimport)) Edition de liens de l’application cliente fichier .lib de librairie d’importation (créé en même temps que le fichier .dll). Il contient : les noms symboliques utilisés pour l’édition de liens du client le nom de fichier de la DLL (mais pas son chemin d’accès) Attention : le fichier .lib contient pas le code des fonctions exportées Exécution de l’application cliente fichier DLL contenant le code des fonctions exportées 8 Génie logiciel – DLL 4 Liens implicites avec des DLL A l’exécution, les noms symboliques exportés du .lib sont mis en correspondance avec les noms symboliques importés du .dll, et sont intégrés au .exe. Windows recherche et charge implicitement la DLL, par défaut au lancement de l’application. Avec les liens implicites, la recherche des DLL par les applications clientes se fait en examinant dans l’ordre : le répertoire qui contient le fichier exécutable .exe le répertoire courant de l’application le répertoire système de Windows C:\WINDOWS\system le répertoire de Windows C:\WINDOWS les répertoires énumérés dans la variable d’environnement PATH Attention aux DLL modifiées mais non propagées. 9 Liens explicites avec des DLL Pas de fichier d’importation (*.lib), mais utilisation de la fonction ::LoadLibrary("chemin\\nom_de_dll") de Win32 - contrôle du moment où la DLL est chargée Application 1 : chargement d’une fonction selon les besoins : extern "C" __declspec (dllimport) double SquareRoot(double d); typedef double (SQRTPROC) (double); HINSTANCE hInst; SQRTPROC* pFunc; VERIFY(hInst = ::LoadLibrary(C:\\Winnt\\system\\MaDll.dll)); VERIFY(pFunc = (SQRTPROC*) ::GetProcAddress((HMODULE) hInst, "SquareRoot")); double d = (*pFunc) (81.0) //appel de la fonction de la DLL Génie logiciel – DLL Application 2 : chargement de ressources en Anglais ou en Français, après sélection de la langue par l’utilisateur 10 5 Ressources et DLL DLL et client sont repérés par une unique valeur HINSTANCE Cette valeur correspond à une adresse virtuelle de début de la DLL (0x10 000 000) ou de l ’exe (0x400 000) Si une application utilise plusieurs DLL, celles-ci sont relogées si elles n’ont pas, par construction, des adresses différentes ::GetModuleHandle() permet de récupérer le handle du fichier passé en paramètre (l’application si ce paramètre est NULL) AfxSetResourceHandle() change le handle des ressources HINSTANCE hInstOld = HINSTANCE hInstNew = AfxSetResourceHandle CreateToolBar (); AfxSetResourceHandle (HINSTANCE) ::GetModuleHandle(NULL); (HINSTANCE)::GetModuleHandle("GetDll.dll"); (hInstNew); (hInstOld); 11 Liens symboliques vs liens ordinaux Liens symboliques noms (décorés) des fonctions ⇒ noms longs ⇒ fichiers .exe plus gros, mais recommandés depuis Win32 Liens ordinaux numéros ⇒ efficacité (diminution taille .exe) ⇒ spécifier les liens ordinaux dans le fichier .def du projet ex : MFC ??0CMapPtrToPtr@@QAE@H@Z @ 394 NONAME ??0CMapPtrToWord@@QAE@H@Z @ 395 NONAME ??0CMapStringToOb@@QAE@H@Z @ 396 NONAME ??0CMapStringToPtr@@QAE@H@Z @ 397 NONAME ??0CMapStringToString@@QAE@H@Z @ 398 NONAME 12 Génie logiciel – DLL 6 Création d’une DLL Avec Visual C++ .NET possibilité de créer DEUX types de DLL DLL d’extension MFC DLL conventionnelle 13 DLL d’extension MFC Dynamiquement liée à la bibliothèque MFC (option par défaut dans AppWizard) application cliente dynamiquement liée à la bibliothèque MFC ⇒ application et DLL synchronisées sur la même version DLL de MFC (attention aux changements de version de VC++) ⇒ Supporte une interface C++ ⇒ la DLL d ’extension peut exporter des classes entières, que le client peut instancier ou dériver Taille réduite des DLL créées (liaison dyn. avec MFC) ⇒ temps de chargement réduit 14 Génie logiciel – DLL 7 DLL conventionnelles Requises si une application générée par n’importe quel environnement de développement utilise la DLL créée Ne peuvent exporter que des fonctions de style C ⇒ pas d’exportation de classes C++, ni de fonctions membres, ni de fonctions surchargées (chaque compilateur C++ à sa propre méthode pour générer des noms décorés) utilisation possible de classes C++ dans la DLL (⊂ MFC) Liées statiquement (> 110 ko) ou dynamiquement (≈ 20 ko) à la bibliothèque MFC 15 Constantes #define et DLL En indiquant à AppWizard le type d’exe ou de dll choisi, les constantes #define sont configurées selon : Lié dynamiquement à la bibliothèque MFC DLL conventionnelle _AFXDLL, _USRDLL _AFXEXT, _AFXDLL DLL d'extension _AFXDLL EXE client Lié statiquement à la bibliothèque MFC _USRDLL Pas de constantes définies De nombreuses directives #ifdef relatives à ces constantes sont présentes dans les fichiers .h et .cpp des MFC, indiquant des compilations qui dépendent de la nature des projets créés. 16 Génie logiciel – DLL 8 Exportation de classes L’exportation des classes est uniquement possible pour les DLL d’extension MFC. AppWizard génère un squelette simplifié pour les DLL d’extension, qui ne contient que la fonction DllMain(). Pour inclure dans la DLL des classes personnelles, il suffit d’ajouter la macro AFX_EXT_CLASS : class AFX_EXT_CLASS CNouvelle : public CObject {…} Cette modification doit être réalisée dans le fichier .h de la DLL et dans celui utilisé par l’application cliente. 17 Génie logiciel Rappels SPE4 - ESI Année 2005-2006 18 Génie logiciel – DLL 9 L’affichage des diagnostics Outils permettant d’afficher des diagnostics. La macro TRACE : Fonctionne comme l’instruction printf du C, mais elle est complètement désactivée dans la version release de l’application int a=2; TRACE(« Valeur : %d",a); L’objet afxDump : Plus compatible avec le C++. Syntaxe semblable à celle de cout. int a=2; afxDump<<« valeur »<<a; 19 Polymorphisme Main() { CClassA CClassA *cl; CClassA() ~CClassA() void Aff(){cout<<‘ A ‘;} CClassB CClassC CClassB() ~CClassB() void Aff(){cout<<‘ B ‘;} CClassC() ~CClassC () void Aff(){cout<<‘ C ‘;} cl = new CClassA(); cl->Aff(); // Affiche ? delete cl; cl = new CClassB(); cl->Aff(); // Affiche ? delete cl; cl = new CClassC(); cl->Aff(); // Affiche ? delete cl; } 20 Génie logiciel – DLL 10 Polymorphisme Si dans les classes d’une hiérarchie, plusieurs implémentations d’une même fonction membre sont définies, le programme d’application peut alors les utiliser sans connaître le type (classe) de l’objet courant au moment de la compilation. C’est pendant l’exécution du programme que le système sélectionne la fonction membre à appeler, en fonction du type de l’objet courant. 21 Fonction virtuelle pure Une classe abstraite est une classe de base qui regroupe des caractéristiques communes à toute une hiérarchie de classes. Dans la mesure où ces classes dérivées la complètent, cette classe de base ne doit généralement pas être instanciée. Pour interdire l’instanciation de cette classe, on donne alors à cette classe une fonction membre virtuelle pure, publique : virtual type fonction = 0; 22 Génie logiciel – DLL 11