Utiliser les apis de dlls sans avoir le fichier .lib

Soyez le premier à donner votre avis sur cette source.

Vue 7 608 fois - Téléchargée 459 fois

Description

Ceci permet d'utiliser APIs de DLLs sans avoir le fichier .lib qui nous manque parfois de façon complète et relativement simplement.

C'est ma première source C++ (je fesais du VB avant) donc soyez pas trop chiens s.v.p

Source / Exemple :


//À 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
}

Conclusion :


Alors? Pour plus d'explications, veuillez me les demander.

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

racpp
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
7 -
Salut,
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.
BlackGoddess
Messages postés
338
Date d'inscription
jeudi 22 août 2002
Statut
Membre
Dernière intervention
14 juin 2005
-
lors d'une déclaration
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.
DeadlyPredator
Messages postés
222
Date d'inscription
jeudi 15 janvier 2004
Statut
Membre
Dernière intervention
30 juin 2008
-
c'est possible BlackGoddess que les 2 méthodes aient la même vitesse. Mais alors pourquoi vb6 n'utilise pas une des 2 méthodes et qu'il appelle une api qui appelle une autre api?
BlackGoddess
Messages postés
338
Date d'inscription
jeudi 22 août 2002
Statut
Membre
Dernière intervention
14 juin 2005
-
également, avec le liage dynamique, l'exportation directe de classes en C++ n'est pas possible.
BlackGoddess
Messages postés
338
Date d'inscription
jeudi 22 août 2002
Statut
Membre
Dernière intervention
14 juin 2005
-
euh ... dans le cas du liage statique, le nom des dll et de leurs fonctions utilisées sont écrit dans la section importation de l'executable. C'est l'OS qui charge toutes les dll décrites dans la section en meme temps que l'executable, et qui les décharge en meme temps que l'executable (sauf si elles sont partagées, et encore le partage ne marche que sur les NT je crois, bref). Si une dll ou une fonction exportée n'est pas trouvée, l'os met un message d'erreur et ne charge pas l'executable.
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.