Utiliser les fonctions d'une DLL chargée dynamiquement [Résolu]

Signaler
Messages postés
23
Date d'inscription
vendredi 14 mars 2003
Statut
Membre
Dernière intervention
14 janvier 2005
-
Messages postés
2676
Date d'inscription
vendredi 28 juin 2002
Statut
Membre
Dernière intervention
13 janvier 2016
-
Si on se sert d'une DLL en la chargeant dynamiquement, donc sans utiliser "Declare Function"...
On utilise donc "LoadLibrary" et "GetProcAddress" pour récupérer l'adresse de la fonction dont on a besoin.

Question : comment utiliser la fonction après avoir récupéré son point d'entrée ?

Au cas-où, pour mon cas, j'écris les fonctions dont j'ai besoin ainsi que les types utilisés :

Type RARHeaderData
ArcName As String * 260
FileName As String * 260
Flags As Long
PackSize As Long
UnpSize As Long
HostOS As Long
FileCRC As Long
FILETIME As Long
UnpVer As Long
Method As Long
FileAttr As Long
CmtBuf As String
CmtBufSize As Long
CmtSize As Long
CmtState As Long
End Type


Type RAROpenArchiveData
ArcName As String
OpenMode As Long
OpenResult As Long
CmtBuf As String
CmtBufSize As Long
CmtSize As Long
CmtState As Long
End Type


Declare Function RAROpenArchive Lib "unrar.dll" (ByRef ArchiveData As RAROpenArchiveData) As Long

Declare Function RARCloseArchive Lib "unrar.dll" (ByVal hArcData As Long) As Long

Declare Function RARReadHeader Lib "unrar.dll" (ByVal hArcData As Long, ByRef HeaderData As RARHeaderData) As Long

Declare Function RARProcessFile Lib "unrar.dll" (ByVal hArcData As Long, ByVal Operation As Long, ByVal DestPath As String, ByVal DestName As String) As Long

7 réponses

Messages postés
2676
Date d'inscription
vendredi 28 juin 2002
Statut
Membre
Dernière intervention
13 janvier 2016
20
salut,


déjà le handle d'une dll (HMODULE) c'est l'adresse de base dela dll en mémoire (l'adresse à laquelle elle est chargée)...


Ensuite CallWindowProc est le seul moyen facile d'utiliser un point d'entrée (pointeur de fonction). Cela limite les fonctions appelées par le nombre de paramètre de la fonction aux 4 paramètres des procédures de fenêtre...


Sinon, pour faire plus compliqué, tu prends IDL (et MIDL.exe ou mktyplib.exe) pour faire une bibliothèque de type avec une interface comprennant le prototype des fonctions que tu veux utiliser avec pour premier paramètre un par valeur de l'adresse de la fonction.

Ensuite, il faut que tu importes cette typelib dans VB, tu declares une variable de type Long pVTable:

Dans un tableau fctptr, tu dois mettre
- un pointeur vers une fonction QueryInterface perso
(This As FunctionDelegator, riid As Long, pvObject As Long) As Long, elle renvoie 0 (et met Varptr(This) dans pvObject) au premier appel et E_NOINTERFACE (et met 0 dans pvObject) ensuite.
- un pointeur vers une fonction AddRef perso
(ByVal This As Long) As Long qui ne fait rien (mettre un ' dans le corps pour éviter la suppression
- un pointeur vers une fonction Release perso
(ByVal This As Long) As Long qui ne fait rien (mettre un ' dans le corps pour éviter la suppression
- autant de pointeur vers une variable contenant le code asm (en binaire) que de fonctions API dans l'interface :
pop ecx ; l'adresse de retour
pop eax ; le pointeur this (pas besoin pour les appels d'apis)
pop eax ; le pointeur de fonction (premier paramètre (par valeur))
jmp eax ; saut au début de l'api


Ensuite, tu dois mettre l'adresse du tableau de pointeurs de fonctions dans ta var :
pVTable = vartr(fctptr(0))


Ensuite, tu copies pVTable dans ta_var du type de ton interface :
CopyMemory ta_var,Byval VarPtr(pVTable),4&

c'est quand même assez compliqué, pour moi, je trouve ca utile si tu ne peutx pas faire avec declare (pointeurs de fonction non exportés, cdecl, ...)
si ca t'intéresse vraiment je te conseille "Advanced Visual Basic 6" de M. Curland... cet technique fait partie du livre...


ShareVB
3
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 179 internautes nous ont dit merci ce mois-ci

Messages postés
2676
Date d'inscription
vendredi 28 juin 2002
Statut
Membre
Dernière intervention
13 janvier 2016
20
salut,

les declare, c'est déjà du chargement dynamique...en outre, en vb, pas de pointeurs de fonctions donc pas de GetProcAddress...si tu regardes avec Depends.exe, tu ne trouveras pas les fonctions que tu as déclarées. (Si tu veux avoir la liste des declares d'un exe : http://www.vbfrance.com/code.aspx?id=28572)

ShareVB
Messages postés
23
Date d'inscription
vendredi 14 mars 2003
Statut
Membre
Dernière intervention
14 janvier 2005

Hmm, il y a 2-3 sources sur le sujet. Le but c'est de trouver le Handle de la dll, de la fonction et d'utiliser les API de Windows pour pouvoir s'en servir. Mais les sources postées sont uniquement basées sur l'API CallWindowProc...
Y'a certes pas de pointeur en VB, mais le but est justement de contourner le problème en se servant des API de Windows. A croire que pour y arriver, il y a de sacrées magouilles à faire. Bref, je vais essayer de chercher un peu, en espérant que qqun s'est déjà amusé sur le sujet.

En tout cas, je te remercie de m'avoir répondu. :-)
Messages postés
23
Date d'inscription
vendredi 14 mars 2003
Statut
Membre
Dernière intervention
14 janvier 2005

Euh, je voulais dire de charger la dll, pas trouver le handle.
Messages postés
23
Date d'inscription
vendredi 14 mars 2003
Statut
Membre
Dernière intervention
14 janvier 2005

Hello,

Ne t'inquiète pas, je sais ce qu'est un handle, on va dire que j'ai passé le stade de débutant... :oP
Merci de ta réponse, je vois que j'ai affaire à un maître. J'avais pas vu que c'était ce cher ShareVB dont tout le monde parle (fais gaffe, je vais bientôt te demander de l'argent...).

Concernant CallWindowProc, comme tu dis c'est limité. De plus, l'API ne "s'adresse" qu'aux fenêtres si je me trompe pas.

Bref, concernant la deuxième méthode, je comprends plus ou moins le fonctionnement, Mais quand tu me parles d'IDL, je suis largué... J'ai un peu cherché, mais quitte à trier des centaines de pages, je préfère te demander si tu ne connais pas un site qui explique un peu ça stp.
Ensuite tu dis :
"- autant de pointeur vers une variable contenant le code asm (en binaire) que de fonctions API dans l'interface"
Donc en fin de compte, j'ai peut-être rien capté... Tu récupère quoi exactement, le code asm ?
Là oui, je suis un débutant fini, désolé.
Messages postés
2676
Date d'inscription
vendredi 28 juin 2002
Statut
Membre
Dernière intervention
13 janvier 2016
20
salut,

Je crois CallWindowProc peut être détourner de son utilisation première pour appeler des fonctions qui ne sont pas forcément de fenêtre.

Ensuite, IDL est le langage de définition d'interface abondement utlisé pour créer les fichiers tlb (ce que l'on voit dans l'explorateur d'objet, c'est le contenu des tlbs de VB). Cela sert à définir toutes les interfaces COM genre IMachinTruc (par ex IPictureDisp)...
Il existe deux outils pour créer des tlb à partie de fichiers IDL ou ODL (plus ancien) : mktyplib.exe (très facile d'utilisation : utilise ODL...ce qui est très adapté à VB : tlb simple) et MIDL.exe (très complexe et pas facile à compilé un IDL avec...)
un IDL, c'est du genre :
[
uuid(2F6CA420-C641-101A-B826-00DD01103DE1), // à générer avec GUIDGEN.EXE
helpstring("Ta tlb1.0"),
version(1.0)
]
library TaTLB
{
#ifdef WIN32
importlib("stdole32.tlb");
#else
importlib("stdole.tlb");
#endif

typedef tagRAROpenArchiveData {
long ArcName;
long OpenMode;
long OpenResult;
long CmtBuf;
long CmtBufSize;
long CmtSize;
long CmtState;
} RAROpenArchiveData;

[
uuid(2F6CA422-C641-101A-B826-00DD01103DE1), // pareil
helpstring("Ton Interface")
]
interface IRar : IUnknown
{
long RAROpenArchive(long lpFctPtr, RAROpenArchiveData* lpArchiveData);
//ainsi de suite
}
}

bon, j'ai pas testé... masi ca devrait être à peut près ca...sinon, il y a la doc de MIDL :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnanchor/html/midl.asp
enfin, tu met dans une variable (ou un tableau) le code binaire exécutable correspondant aux instructions ASM que je t'ai donné (par POP ECX 59h, POP EAX 58h)...je crois que ca doit tenir dans un double ou currency XXXXXXXXXX585859h et si tu as trop de XX tu met 90h = NOP (no operating code) (on sait jamais)...

ShareVB
Messages postés
2676
Date d'inscription
vendredi 28 juin 2002
Statut
Membre
Dernière intervention
13 janvier 2016
20
salut,

oupss, j'ai oublié une instruction ASM :

pop ecx ; l'adresse de retour
pop eax ; le pointeur this (pas besoin pour les appels d'apis)
pop eax ; le pointeur de fonction (premier paramètre (par valeur))
push ecx ;ne pas oublier de remettre l'adresse de retour
jmp eax ; saut au début de l'api

ShareVB