Soyez le premier à donner votre avis sur cette source.
Vue 7 754 fois - Téléchargée 513 fois
//À mettre dans un fichier .h appart qui sera à include //Mettre les définitions d'API ici //Comment on défénit le type d'une API? Regardez : //typedef %type de ce que retourne l'API% (%Convention d'appel%)* %le nom de ce nouveau type%) (%les paramètres de l'API%); //%le nom du type de l'API% %le nom de la variable qui contiendra l'API%; //En général, __stdcall sera la convention d'appel requise mais il ce peut que ce soit __cdecl typedef int (__stdcall* apiMsgBox) (HWND Handle, LPCSTR Texte, LPCSTR Titre, UINT Flags); apiMsgBox MonMsgBox; typedef int (__stdcall* apiGetTickCount) (void); apiGetTickCount MonGetTickCount; typedef void (__cdecl* apitest) (LPCSTR a, int b); //LA CONVENTION D'APPEL PAR DÉFAULT EN C++ EST __cdecl donc il ne faut pas __stdcall mais rien ou __cdecl apitest Montest; //} HMODULE hmodDlls[1];//Dans ce tableau, on stock les modules int Count=1;//On Commence à 1 void InitializeAPIs()//Cette fonction initialize les APIs { hmodDlls[Count]=LoadLibrary(TEXT("User32.dll"));//On load la DLL User32.dll if (!hmodDlls[Count]==0){cout << "Chargement du module #" << Count << " : " << hmodDlls[Count] << "\n";}else{cout << "Impossible de charger le module #" << Count << "!\n";} MonMsgBox=(apiMsgBox)GetProcAddress(hmodDlls[Count],TEXT("MessageBoxA")); //La variable MonMsgBox (qui est du type apiMsgBox) reçcit comme valeur un pointeur vers la fonction MessageBoxA de User32.dll //Si on voudrait déclarer une nouvelle API qui est dans User32.dll, on le ferait ICI Count++;//Quand on a fini avec un module, on incrémente Count pour faire de la place pour un nouveau module si on en a besoins //Nouveau module : Kernel32.dll hmodDlls[Count]=LoadLibrary(TEXT("Kernel32.dll"));//On load la DLL User32.dll if (!hmodDlls[Count]==0){cout << "Chargement du module #" << Count << " : " << hmodDlls[Count] << "\n";}else{cout << "Impossible de charger le module #" << Count << "!\n";} MonGetTickCount=(apiGetTickCount)GetProcAddress(hmodDlls[Count],TEXT("GetTickCount"));//... Count++; hmodDlls[Count]=LoadLibrary(TEXT("Ma dll.dll"));//On load la DLL Drole.dll (que j'ai fait en C++) if (!hmodDlls[Count]==0){cout << "Chargement du module #" << Count << " : " << hmodDlls[Count] << "\n";}else{cout << "Impossible de charger le module #" << Count << "!\n";} Montest=(apitest)GetProcAddress(hmodDlls[Count],TEXT("test"));//... cout << "\n\n";//laisser deux lignes vides } void TerminateAPIs()//Tout nettoyer { for(int i = 1; i <= Count ; i++)//Pour chaque module qu'on a loader { cout << "Nettoyage du module #" << i << " : " << hmodDlls[i] << "\n";//Dire que le module à été nettoyer FreeLibrary(hmodDlls[i]);//Relacher le module } cout << "\n";//laisser une ligne vide à la fin }
Voici ce que dit Microsoft :
La plupart des applications utilisent la liaison implicite (statique) car c'est la méthode de liaison la plus simple à adopter. Cependant, la liaison explicite (dynamique) est parfois nécessaire. Voici quelques raisons courantes qui justifient l'utilisation de la liaison explicite :
1) L'application ne découvre le nom d'une DLL qu'elle doit charger qu'au moment de l'exécution. Par exemple, l'application peut avoir besoin d'obtenir le nom de la DLL et des fonctions exportées à partir d'un fichier de configuration.
2) Un processus utilisant la liaison implicite est interrompu par le système d'exploitation si la DLL est introuvable au moment du démarrage du processus. Un processus utilisant la liaison explicite n'est pas interrompu dans ce cas et peut essayer de récupérer à partir de l'erreur. Par exemple, le processus peut signaler l'erreur à l'utilisateur et lui demander de spécifier un autre chemin d'accès de la DLL.
3) Un processus qui utilise la liaison implicite est également interrompu si l'une des DLL auxquelles il est lié possède une fonction DllMain qui échoue. Un processus utilisant la liaison explicite n'est pas interrompu dans ce cas.
4) Une application liée de manière implicite à de nombreuses DLL peut être lente à démarrer car Windows charge toutes les DLL en même temps que l'application. Pour accélérer le démarrage, une application peut être liée de manière implicite aux DLL requises immédiatement après le chargement, puis attendre d'être liée explicitement aux autres DLL au fur et à mesure des besoins.
5) Avec la liaison explicite, il n'est plus nécessaire de lier l'application à une bibliothèque d'importation. Si les ordinaux d'exportation changent à la suite de modifications apportées à la DLL, les applications utilisant la liaison explicite n'ont pas besoin d'être rééditées (à supposer qu'elles appellent GetProcAddress à l'aide d'un nom de fonction et non avec une valeur ordinale), alors que les applications utilisant la liaison implicite doivent subir une réédition de leurs liens avec la nouvelle bibliothèque d'importation.
declare sub ... alias ... lib ... ( ... )
vb6 ne fait rien. par contre au 1er appel d'une des fonctions, la dll est chargée dynamiquement (LoadLibrary) (par une des dll vb6, qui elle est liée statiquement à l'executable) puis la fonction executée. La dll est déchargée a la fin du processus.
Dans le cas du liage dynamique, c'est a l'executable de charger lui meme ses DLLs (LoadLybraryA, FreeLibrary, GetProcAddress). c'est à lui de gérer si une dll n'est pas trouvé également.
A part qu'elle n'est pas chargée au meme moment, c'est la meme chose... (gardons a l'esprit également que kernel32.dll devra probablement etre liée statiquement : en effet, comment appeler LoadLibraryA pour utiliser kernel32.dll si c'est elle meme qui exporte la fonction ?
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.