Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2970 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Chargement de fonction d'une librairie DLL

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Chargement de fonction d'une librairie DLL

n°425345
Profil sup​primé
Posté le 12-06-2003 à 17:59:08  answer
 

Auriez vous quelques informations ou explications à propos des chargements de librairies DLL et de récupération des fonctions contenues dans cette librairie. Je dois être capable d'expliquer ce programme ! C'est le FAR PASCAL et les (FARPROC) Imp_Init=GetProcAddress(hImpDLL, "Imp_Init" );
 
Voici le code complet du petit programme :ange:  

Code :
  1. #include <windows.h>
  2. #include <memory.h>
  3. #include <dos.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <math.h>
  7. #define MAXIMPCARD 8
  8. #define MAXPOLLTAB 50
  9. void (FAR PASCAL *Imp_Init) (short far*,short far*,short far*);
  10. void (FAR PASCAL *Imp_Tx) (short far*,char far*,short far*,short far*,short far*);
  11. void (FAR PASCAL *Imp_Test) (short far*,short far*,short far*,short far*);
  12. void (FAR PASCAL *Imp_String) (short far*,short far*,char far*,short far*,short far*,short far*);
  13. void (FAR PASCAL *Imp_Numeric) (short far*,short far*,short far*,short far*,float far*,short far*,short far*);
  14. void (FAR PASCAL *Imp_ValToByte) (float far*,short far*);
  15. void (FAR PASCAL *Imp_Connect) (unsigned short far*,short far*);
  16. void (FAR PASCAL *Imp_Disconnect) (short far*);
  17. short (FAR PASCAL *Imp_CardInUse) ();
  18. void (FAR PASCAL *Imp_DLLVersion) (char far*);
  19. void (FAR PASCAL *Imp_DLLDelay) (unsigned short);
  20. void (FAR PASCAL *Imp_PowerOff) (short far*);
  21. int LocateCard();
  22. int LoadIMPDrv();
  23. int ImpDrvOK=0;
  24. int ImpCardOK=0;
  25. short CurHand=-1;
  26. unsigned short BaseAddr=0xCA00;
  27. unsigned short CardAddr;
  28. short Poll_Tab[MAXPOLLTAB];
  29. HINSTANCE hImpDLL;
  30. /* Main */
  31. int main()
  32. {
  33.     short CardHandle=-1;
  34.     printf(".: Programme de reconnaissance automatique :.\n\n" );
  35.     ImpDrvOK=LoadIMPDrv();
  36.     if(ImpDrvOK==1)
  37.     {
  38.         printf("Chargement du pilote (IMPDRVR.DLL) --> OK\n\n" );   
  39.        
  40.         ImpCardOK=LocateCard();
  41.         printf("Valeur de retour de LocateCard --> %d\n\n", ImpCardOK); 
  42.         if(ImpCardOK==1)
  43.         {
  44.                 printf("Adresse de la carte %x --> OK\n\n", CardAddr);
  45.         }
  46.        
  47.         if(!Imp_CardInUse()) ImpDrvOK=FreeLibrary(hImpDLL);
  48.         if(ImpDrvOK==1) printf("Liberation du pilote (IMPDRVR.DLL) --> OK\n\n" );     
  49.        
  50.     }
  51.    
  52.    
  53.        
  54.     return 0;
  55. }
  56. /* Chargement du driver */
  57. int LoadIMPDrv()
  58. {
  59.     int LoadStat=0;
  60.  
  61.     hImpDLL=LoadLibrary("IMPDRVR.DLL" );
  62.     if(hImpDLL!=NULL)
  63.     {
  64.         (FARPROC) Imp_Init=GetProcAddress(hImpDLL, "Imp_Init" );
  65.         if(Imp_Init!=NULL)
  66.         {
  67.         (FARPROC) Imp_Tx=GetProcAddress(hImpDLL, "Imp_Tx" );
  68.        
  69.         if(Imp_Tx!=NULL)
  70.         {
  71.         (FARPROC) Imp_Test=GetProcAddress(hImpDLL, "Imp_Test" );
  72.        
  73.         if(Imp_Test!=NULL)
  74.         {
  75.         (FARPROC) Imp_String=GetProcAddress(hImpDLL, "Imp_String" );
  76.        
  77.         if(Imp_String!=NULL)
  78.         {
  79.         (FARPROC) Imp_Numeric=GetProcAddress(hImpDLL, "Imp_Numeric" );
  80.        
  81.         if(Imp_Numeric!=NULL)
  82.         {
  83.         (FARPROC) Imp_ValToByte=GetProcAddress(hImpDLL, "Imp_ValToByte" );
  84.         if(Imp_ValToByte!=NULL)
  85.         {
  86.         (FARPROC) Imp_Connect=GetProcAddress(hImpDLL, "Imp_Connect" );
  87.        
  88.         if(Imp_Connect!=NULL)
  89.         {
  90.         (FARPROC) Imp_Disconnect=GetProcAddress(hImpDLL, "Imp_Disconnect" );
  91.        
  92.         if(Imp_Disconnect!=NULL)
  93.         {
  94.         (FARPROC) Imp_CardInUse=GetProcAddress(hImpDLL, "Imp_CardInUse" );
  95.        
  96.         if(Imp_CardInUse!=NULL)
  97.         {
  98.         (FARPROC) Imp_DLLVersion=GetProcAddress(hImpDLL, "Imp_DLLVersion" );
  99.        
  100.         if(Imp_DLLVersion!=NULL)
  101.         {
  102.         (FARPROC) Imp_DLLDelay=GetProcAddress(hImpDLL, "Imp_DLLDelay" );
  103.       
  104.         if(Imp_DLLDelay!=NULL)
  105.         {
  106.         (FARPROC) Imp_PowerOff=GetProcAddress(hImpDLL, "Imp_PowerOff" );
  107.        
  108.         if (Imp_PowerOff!=NULL)
  109.         {
  110.                 LoadStat=1; /* Flag de chargement correct */
  111.        
  112.         }}}}}}}}}}}}
  113.        
  114.                 if(!LoadStat)
  115.                 {
  116.                                 printf("Erreur de chargement du pilote (IMPDRVR.DLL)\n" );           
  117.                 }
  118.         }
  119.         else
  120.         {
  121.                 printf("Impossible de charger le pilote (IMPDRVR.DLL)\n" );
  122.         }
  123.    
  124.     return (LoadStat);   
  125. }
  126. int LocateCard()
  127. {
  128.     char LpExit=0;
  129.     int AdapFound=0;
  130.     short InitStat=0;
  131.     CardAddr=BaseAddr;
  132.    
  133.     while(!LpExit)
  134.     {
  135.         Imp_Connect(& CardAddr, & CurHand);
  136.         if(CurHand>=0)
  137.         {
  138.                 Imp_Init(& Poll_Tab[0], & InitStat, & CurHand);
  139.                 if(!InitStat)
  140.                 {
  141.                                 LpExit=1;
  142.                                 AdapFound=1;
  143.                 }
  144.                 else
  145.                 {
  146.                                 Imp_Disconnect(& CurHand);
  147.                                 CardAddr+=0x100;
  148.                                 if(CardAddr>0xDFE0) LpExit=2;
  149.                 }
  150.         }
  151.         else
  152.         LpExit=3;
  153.     }
  154.     return (AdapFound);
  155. }


 
 
@ plus  :hello:  
Jardy

mood
Publicité
Posté le 12-06-2003 à 17:59:08  profilanswer
 

n°425428
xWillow
Posté le 12-06-2003 à 19:44:37  profilanswer
 

c'est nickel bien codé, parfaitement comprehensible, parfais, rien a dire =)

n°425429
xWillow
Posté le 12-06-2003 à 19:44:51  profilanswer
 

la suite de if la est splendide :)
toutes les variables sont declarées en global, c'est mal.
tu veux savoir quoi exactement ?


Message édité par xWillow le 12-06-2003 à 19:52:20
n°425538
Profil sup​primé
Posté le 12-06-2003 à 21:43:55  answer
 

Le truc de FAR PASCAL et GetProcAddress( )
 
Le reste c'est facile, j'aimerais juste des explications sur la déclarations des fonctions. ces même fonctions qui ne sont pas définies dans le code mais dans la librairie ... enfin je crois  :sweat:  :hello:  
 

n°425694
xWillow
Posté le 12-06-2003 à 23:59:41  profilanswer
 

bin y a pas grand chose a dire a part que getprocaddr choppe l'adresse de la fonction.
pour le FAR PASCAL je suis meme pas sur que ce soit necessaire
 
edit: je rectifie c'est sans doute utile mais je sais pas comment ca fonctionne


Message édité par xWillow le 13-06-2003 à 00:01:30
n°425752
chrisbk
-
Posté le 13-06-2003 à 08:07:31  profilanswer
 

ls PASCAL me semble que c'est un #define de _stdcall qui est la convention d'appel de fonction. tu peux effectivement t'en passer si ta fonction retourne char/short/int/void/float/double et ne prends pas de param sinon ca peut mener a des pb. (Si la fonction dans ta dll est declaré avec __stdcall / PASCAL et que tu l'utilises sans (c a d avec _cdecl) ca va merder)
 
le FAR je sais pas


Message édité par chrisbk le 13-06-2003 à 08:07:57
n°425775
blackgodde​ss
vive le troll !
Posté le 13-06-2003 à 08:46:17  profilanswer
 

dans la lib de vc++ ou c'etait déclaré, j'ai vu
#define FAR
donc il servait a rien ...


---------------
-( BlackGoddess )-
n°425786
chrisbk
-
Posté le 13-06-2003 à 08:48:29  profilanswer
 

BlackGoddess a écrit :

dans la lib de vc++ ou c'etait déclaré, j'ai vu
#define FAR
donc il servait a rien ...


 
ca doit etre un relicat des temps ancien alors :D

n°426124
El_gringo
Posté le 13-06-2003 à 10:21:14  profilanswer
 

chrisbk a écrit :


 
ca doit etre un relicat des temps ancien alors :D


 
Exact. ça vient du 16Bits, ou il y avait des pointeur distants et ds pointeurs locaux, un truc dans l'genre.

n°428806
Profil sup​primé
Posté le 16-06-2003 à 10:19:17  answer
 

Ce que je comprends pas c'est
 
--> void (FAR PASCAL *Imp_Init) (short far*,short far*,short far*);
Alors ça c'est la déclaration ...
 
ainsi que
--> (FARPROC) Imp_Init=GetProcAddress(hImpDLL, "Imp_Init" );
Et ça c'est la récupération de l'adresse dans la DLL ...
 
J'aimerais comprendre ces espèces de type bizarres
FAR PASCAL et FARPROC

 
Merci pour les renseignements  :hello:  :bounce:

mood
Publicité
Posté le 16-06-2003 à 10:19:17  profilanswer
 

n°428835
HelloWorld
Salut tout le monde!
Posté le 16-06-2003 à 10:49:38  profilanswer
 

Ca date des Win 3.1 ca.
C'était du 16 bits. Y'avait 2 type de pointeur : les 16 bits (OFFSET), qui limitent à 64Ko, et les pseudo 32 bits (SEGMENT + OFFSET), pseudo cas si c'était bien codé sur 32 bits, c'est pas comparable au 32 bits actuels. On avait droit à 1Mo. Ce dernier pointeur étaient des pointeur FAR (nécessitent un FAR CALL au niveau assembleur).
Voilà pour le FAR. Dès que ton exe fait + de 64Ko, il faut des pointeur FAR sur tes fonctions. Comme on charge des dll, situées dans un autre segment de code, => pointeur FAR.
Après, PASCAL c'est une convention d'appel comme te l'a dit chrisbk.
Ca été abandonné parce que, je crois, PASCAL est toujours __stdcall, alors que WINAPI peut être différent (sous Mac notamment), ou éventuellement, être un jour différent.
 
Je viens de jeter un oeil à windef.h :

Code :
  1. #ifdef _MAC
  2.     #define CALLBACK    PASCAL
  3.     #define WINAPI      CDECL
  4.     #define WINAPIV     CDECL
  5.     #define APIENTRY    WINAPI
  6.     #define APIPRIVATE  CDECL
  7.     #ifdef _68K_
  8.         #define PASCAL      __pascal
  9.     #else
  10.         #define PASCAL
  11.     #endif
  12. #elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
  13.     #define CALLBACK    __stdcall
  14.     #define WINAPI      __stdcall
  15.     #define WINAPIV     __cdecl
  16.     #define APIENTRY    WINAPI
  17.     #define APIPRIVATE  __stdcall
  18.     #define PASCAL      __stdcall
  19. #else
  20.     #define CALLBACK
  21.     #define WINAPI
  22.     #define WINAPIV
  23.     #define APIENTRY    WINAPI
  24.     #define APIPRIVATE
  25.     #define PASCAL      pascal
  26. #endif


 
Bon ben PASCAL est différent selon les sytèmes alors. Je sais pas pourquoi ils ont changé PASCAL pour WINAPI, peut être simplement pour le style.
Voila. J'espère ne pas avoir trop dit de betises vu que j'ai jamais codé sous Win 3x (notamment, je sais pas comment ca se passe pour les 286). Mais en gros ca doit etre ca.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°429248
Profil sup​primé
Posté le 16-06-2003 à 14:29:52  answer
 

Bien sympathique ces explications ... Je te remercie :sol:

n°429632
bjone
Insert booze to continue
Posté le 16-06-2003 à 17:15:50  profilanswer
 

le FAR "peut" être toujours valable, car étant en mode protégé, tu peux avoir des appels inter-segment via des adresse 16:32 bits (alignées sur 64 bits il me semble, donc 16 bits de perdus).  
 
mais je sais pas si ça se passe au niveau du code compilé pour l'appli, les DLL systèmes, ou le code exécuté par le vecteur d'interruption pour sauter au noyau...
 
après pour être sûr, il faudrait savoir de quoi viens le source... (appli win16 ou win32 ?, vu le code c'est du win16)


Message édité par bjone le 16-06-2003 à 17:23:33
n°429755
HelloWorld
Salut tout le monde!
Posté le 16-06-2003 à 18:48:19  profilanswer
 

Appel inter-segment en 32 bits ?
Je croyais qu'il fallait être privilégié pour changer la valeur d'un registre de (descipteur de) segment ... ?


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°430171
bjone
Insert booze to continue
Posté le 17-06-2003 à 10:34:19  profilanswer
 

c ptet (oups) possible, j'ai jamais essayé encore...
 
mais chose sûr, tu ne peux pas changer vers un sélecteur (segment) dont le niveau de privilège est plus haut.
 
mais peut être que dans les API bas-niveau, il possible de créer plusieurs segment de donnée pour avoir plus de ressources (vu qu'un process win32 a 2Go de données par défaut (les 2Go supérieures sont mappées vers le code des DLLs je crois), et qu'il faut compiler avec une option spéciale pour pouvoir avoir 3Go.
 
Donc dans le cas ou on aurait plus de 4Go de ram avec windows en mode PAE, je pense qu'ils ont dû laisser la possiblité d'avoir plusieurs segments de données  :??:  :) (je vais faire un tour dans la MSDN, vu que j'aimerai bien savoir ce qu'il est possible de faire à ce niveau)


Message édité par bjone le 17-06-2003 à 11:25:21
n°430175
bjone
Insert booze to continue
Posté le 17-06-2003 à 10:36:52  profilanswer
 

parallèlement je sais (dumoins crois) que sous les noyaux NT, le kernel n'utilise que deux niveau de privilèges (le ring 0 pour le noyau, et le 3 je crois pour les applis), mais par exemple OS/2 utilise les 4 niveaux de privilèges du mode protégé x86 (0 pour le kernel, 1 pour les drivers bas-niveau, 2 pour les "services", et le 3 pour les process utilisateur).

n°430202
bjone
Insert booze to continue
Posté le 17-06-2003 à 10:54:07  profilanswer
 

héhé je crois que j'ai trouvé une coquille chez crosoft:
http://msdn.microsoft.com/library/ [...] pre_47.asp

n°430233
bjone
Insert booze to continue
Posté le 17-06-2003 à 11:20:53  profilanswer
 

bon apparement y'a pas moyen de créer plusieurs segment de donnée, pour le mode PAE c'est une fenêtre qui est mappée par le mmu pour attendre la mémoire au dessus des 4 Gos....
 
http://www.winntmag.com/Articles/I [...] 1&show=685
 
http://msdn.microsoft.com/library/ [...] nsions.asp
 

n°430670
Profil sup​primé
Posté le 17-06-2003 à 15:25:28  answer
 

Je confirme c'est un extrait de code d'une application win16 sous win3.1

n°430841
bjone
Insert booze to continue
Posté le 17-06-2003 à 17:06:16  profilanswer
 

ok c'est bien ce que je pensais...
 
tu comptes l'utiliser via une appli win16, ou tout refaire pour le win32 ? (pb dans le cas d'un windows nt)

n°430965
Profil sup​primé
Posté le 17-06-2003 à 18:36:13  answer
 

L'executable compilé marche parfaitement sous WinNT je bosse sur cet OS  :sweat:

n°436669
blackgodde​ss
vive le troll !
Posté le 23-06-2003 à 13:25:30  profilanswer
 

qq1 saurait ou trouver des cours sur le chargement des dll, sur le systeme, sur le vecteur d'interruption, les registres, etc ?
 
parce que ca m'interresse bcp, mais c du chinois pour moi tout ca ...
(plutot sous noyau nt5 si possible, mais reprendre plus tot depuis win16 m'interresse aussi :) )


---------------
-( BlackGoddess )-
n°436672
chrisbk
-
Posté le 23-06-2003 à 13:26:40  profilanswer
 

tu veux savoir faire ca en C ? (eg charger une DLL )  
paske c pas bien compliqué, genre 4 fonctions :D

n°436714
blackgodde​ss
vive le troll !
Posté le 23-06-2003 à 13:44:20  profilanswer
 

non, independemment du c, je voudrais savoir comment ca fonctionne (par exemple est-ce le noyau qui charge une dll ? ou est-elle chargée ? etc)


---------------
-( BlackGoddess )-
n°437147
HelloWorld
Salut tout le monde!
Posté le 23-06-2003 à 17:44:39  profilanswer
 

Y'a des bouquins là dessus. Pour des infos sur le fonctionnement des dll, tu peux chercher de la doc sur le format PE. Tu verras le chargement des dll, l'édition dynamique des liens, la rellocation, ...


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°437223
blackgodde​ss
vive le troll !
Posté le 23-06-2003 à 18:44:54  profilanswer
 

qq1 aurait une url ? ou une référence de bouquin ?


---------------
-( BlackGoddess )-
n°437225
blackgodde​ss
vive le troll !
Posté le 23-06-2003 à 18:45:21  profilanswer
 

je me suis un peu documenté sur le format PE, mais je voudrais creuser plus profondement le sujet


---------------
-( BlackGoddess )-
n°437726
HelloWorld
Salut tout le monde!
Posté le 24-06-2003 à 10:00:20  profilanswer
 
n°437965
blackgodde​ss
vive le troll !
Posté le 24-06-2003 à 13:42:37  profilanswer
 

mci :)


---------------
-( BlackGoddess )-
mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Chargement de fonction d'une librairie DLL

 

Sujets relatifs
Cree un fonction cadie pour un site de vente[PHP] ça sert à quoi le @ devant une fonction ?
Lenteur de la fonction CopyFile() !!!runtime.exec() d'une fonction dans un autre répertoire ... [Résolu]
[vbscript]-besoin d'aide sur une fonction[E-Commerce] pb de passage de paramètre à une fonction
Meilleure méthode pour utiliser un vecteur dans une fonctionappel de fonction/de l'aide pour un touriste
Fonction qui retourne un char*Fonction équivalent à fgetcsv() de PHP ?
Plus de sujets relatifs à : Chargement de fonction d'une librairie DLL


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR