[Divers / Ada ] Utiliser un bibliothèque partagé (inpout32.ddl)

Utiliser un bibliothèque partagé (inpout32.ddl) [Divers / Ada ] - Divers - Programmation

Marsh Posté le 15-11-2011 à 20:37:31    

Bonjour,
Je rencontre un problème avec un petit programme écrit avec Ada pour piloter un afficheur LCD ; En effet, dans mon code Ada, j'ai écrit deux routines en langage machine faisant appel à in et out, opérations que je devrais exécuter en mode noyau via un pilote.
 
J'aurais aimé savoir en quoi consiste le développement d'un drivers pour Windows, et comment l'exploiter avec mon petit programme de rien du tout.
 
Merci pour vos lumières.
Voici mes deux routine asm englobées avec Ada.

Code :
  1. procedure Put(Msg : in Message_Type; Value : in Unsigned_8) is
  2.  
  3.   begin
  4.  
  5.      Asm("mov %1,   %%al" & LF & HT &
  6.            "mov %0,   %%dx" & LF & HT &
  7.            "out %%al, %%dx",
  8.          Inputs  => (Unsigned_16'Asm_Input ("g", LP+Message_Type'Pos(Msg)), Unsigned_8'Asm_Input ("a", Value)),
  9.          Volatile => True);
  10.   end Put;


Code :
  1. procedure Get(Msg : in Message_Type; Value : out Unsigned_8) is
  2.  
  3.   begin
  4.  
  5.      Asm("mov %1,%%dx" & LF & HT &
  6.            "in %%dx, %%al" & LF & HT &
  7.            "mov %0, %%al",
  8.          Inputs  => (Unsigned_16'Asm_Input ("g", LP+Message_Type'Pos(Msg))),
  9.          Outputs => Unsigned_8'Asm_Output ("=a", Value),
  10.          Volatile => True);
  11.   end Get;


Message édité par Profil supprimé le 16-11-2011 à 13:58:52
Reply

Marsh Posté le 15-11-2011 à 20:37:31   

Reply

Marsh Posté le 15-11-2011 à 21:39:16    

Si tu es sous Windows, alors, au lieu de réinventer la roue, tu vas récupérer la dll Inpout32.dll ici: http://logix4u.net/Legacy_Ports/Pa [...] NT/XP.html
et tu appelles les fonctions de la dll depuis ton code ADA (je suppose que c'est le genre de choses que tu as déjà fait, ça).
En plus, la DLL est particulièrement simple: 2 fonctions, Out32 et Inp32
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 16-11-2011 à 08:26:41    

gilou a écrit :

(je suppose que c'est le genre de choses que tu as déjà fait, ça).
 
A+,


 
Merci Gilou.
 
Non, en fait non, j'ai jamais utilisé de dll.
 
 
 

Reply

Marsh Posté le 16-11-2011 à 10:51:20    

Re,
J'ai téléchargé la bibliothèque Inpout32 mais je ne parviens pas lié mon exécutable. In32 Out32, undifined reference.
 
J'ai fais des import Cpp des deux fonction mais je sais pas comment procéder pour obtenir mon exe.
 

Reply

Marsh Posté le 16-11-2011 à 11:11:47    

J'essaye de générer un ".o" de inpout32 mais j'obetine le message suivant de la part de gcc :
 

E:\LcdParAda_windows\LcdParAda-0.0.0a\src\lib\Inpout32_dll_source>gcc -c -o inpo
ut32.o inpout32drv.cpp
inpout32drv.cpp: In function 'void Out32(short int, short int)':
inpout32drv.cpp:66: error: '_outp' was not declared in this scope
inpout32drv.cpp: In function 'short int Inp32(short int)':
inpout32drv.cpp:101: error: '_inp' was not declared in this scope

Reply

Marsh Posté le 16-11-2011 à 11:52:25    

Non non, inutile. La DLL s'utilise directement, c'est pas la peine de la recompiler.
 
 
// Tu définis des types pointeurs sur les fonctions de la dll
typedef VOID  (CALLBACK* LPFNDLLFUNC1)(SHORT, SHORT);
typedef SHORT (CALLBACK* LPFNDLLFUNC2)(SHORT);
 
// tu définis en variables globales une variable par fonction de la dll avec le pointeur du bon type
LPFNDLLFUNC1 lpfnOut32;      // Function pointer to Out32
LPFNDLLFUNC2 lpfnInp32;      // Function pointer to Inp32
 
// Dans le corps du main de ta fonction, tu fait la liaison avec la DLL
HINSTANCE hDLL;               // Handle to DLL
hDLL = LoadLibrary("inpout32" );  // Chargement dynamique de la DLL en mémoire
if (hDLL != NULL) {
   lpfnOut32 = (LPFNDLLFUNC1)GetProcAddress(hDLL, "Out32" );
   if (!lpfnOut32) {
       // handle the error
       FreeLibrary(hDLL);        
       return SOME_ERROR_CODE;  // a toi de faire ce qu'il faut ici
   }
   lpfnInp32 = (LPFNDLLFUNC2)GetProcAddress(hDLL, "Inp32" );
   if (!lpfnInp32) {
       // handle the error
       FreeLibrary(hDLL);        
       return SOME_ERROR_CODE;  // a toi de faire ce qu'il faut ici
   }
} else {
return SOME_ERROR_CODE;  // a toi de faire ce qu'il faut ici, avec un message comme quoi tu as pas pu charger la DLL
}
 
si ca a marché, tu peux ensuite faire les appels
SHORT portAddress, data;
lpfnOut32(PortAddress, data);
data = lpfnInp32(data);
 
EDIT: Et il faudra faire aussi un FreeLibrary(hDLL);  avant de sortir du programme
Et Si CALLBACK marche pas, adapter le code de McKenzie ici: http://www.codeguru.com/forum/arch [...] 43634.html
 
A+,

Message cité 1 fois
Message édité par gilou le 16-11-2011 à 13:00:30

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 16-11-2011 à 12:52:27    

Euh, je suis avec Ada là.
Désolé si c'était ambigu.

Reply

Marsh Posté le 16-11-2011 à 12:59:35    

Et sous Ada, tu appelles les fonctions de l'API Windows comment?
Edit: Trouvé: http://rosettacode.org/wiki/Call_a [...] ed_library
A+,

Message cité 1 fois
Message édité par gilou le 16-11-2011 à 13:02:15

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 16-11-2011 à 13:05:46    

gilou a écrit :

Et sous Ada, tu appelles les fonctions de l'API Windows comment?
A+,


 
J'en sais rien, j'ai jamais fait.
Je pense que je dois avoir accès une bibliothèque faisant la liaison entre Ada les l'API Windows, un binding Ada de L'API Windows.

Reply

Marsh Posté le 16-11-2011 à 13:49:17    

Merci Gilou !
J'ai suivi la méthode décrite, ça compile et tout, j'ai mon exe, mais je me retrouve avec un accès non valide à la ligne 42 du code suivant au moment de l'exécution :
 

Code :
  1. --
  2. --
  3. with Interfaces.C;
  4. with Ada.Unchecked_Conversion;
  5. with System;
  6. use System;
  7. package body Pp.Pp_Io is
  8.  
  9.   use Interfaces, Interfaces.C;
  10.  
  11.   type HANDLE is new Unsigned_32;
  12.   function LoadLibrary (lpFileName : char_array) return HANDLE;
  13.   pragma Import (stdcall, LoadLibrary, "LoadLibrary", "_LoadLibraryA@4" );
  14.  
  15.   function GetProcAddress (hModule : HANDLE; lpProcName : char_array)
  16.      return Address;
  17.   pragma Import (stdcall, GetProcAddress, "GetProcAddress", "_GetProcAddress@8" );
  18.  
  19.   type Out32_Type is access procedure (Port_Address : in C.Short;
  20.                                        Data : in C.Short);  
  21.   type Inp32_Type is access function (Port_Address : in C.Short) return C.Short;
  22.  
  23.   pragma Convention (Stdcall, Out32_Type);
  24.   pragma Convention (Stdcall, Inp32_Type);
  25.   function To_Out32_Type is new Ada.Unchecked_Conversion (Address, Out32_Type);
  26.   function To_Inp32_Type is new Ada.Unchecked_Conversion (Address, Inp32_Type);
  27.  
  28.   Library : HANDLE  := LoadLibrary (To_C ("inpout32.dll" ));
  29.   Out_Pointer : Address := GetProcAddress (Library, To_C ("out32A" ));
  30.   Inp_Pointer : Address := GetProcAddress (Library, To_C ("inp32A" ));
  31.  
  32.   procedure Put(Msg : in Message_Type; Value : in Unsigned_8) is
  33.  
  34.      
  35.   begin
  36.      To_Out32_Type(Out_Pointer) (C.short(LP+Message_Type'Pos(Msg)), C.Short(Value));
  37.   end Put;
  38.  
  39.   procedure Get(Msg : in Message_Type; Value : out Unsigned_8) is
  40.  
  41.   begin
  42.     Value := Unsigned_8(To_Inp32_Type (Inp_Pointer)(C.short(LP+Message_Type'Pos(Msg))));
  43.   end Get;
  44. end Pp.Pp_Io;

 
 
Je pense que c'est du au nom fournit ligne 29 et 30, où au moins inp32 n'est pas connu.
J'ai essayé avec "inp32", mais ça passe pas non plus.
Une idée ?


Message édité par Profil supprimé le 16-11-2011 à 13:55:51
Reply

Marsh Posté le 16-11-2011 à 13:49:17   

Reply

Marsh Posté le 16-11-2011 à 14:04:50    

C'est tout faux, ce que tu as écrit.
LoadLibrary, ça se fait avec le nom sans extension, et les fonctions n'ont pas un A qui les suit (ce qui est le cas des fonctions de l'API Windows qui ont une version ascii avec A et une unicode avec U je crois).
En plus, pourquoi faire compliqué?
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 16-11-2011 à 14:06:24    

Voilà,
 
Pour les nom de fonction, c'est "Inp32" et "Out32" (maj-'A')
 
Merci Gilou. "bonjour monde !" from Lcd on Windows XP

Reply

Marsh Posté le 16-11-2011 à 14:10:42    

gilou a écrit :

C'est tout faux, ce que tu as écrit.


T'abuse là, ...  :heink:  

gilou a écrit :


LoadLibrary, ça se fait avec le nom sans extension,  


Je teste.... Ca marche aussi.

gilou a écrit :


et les fonctions n'ont pas un A qui les suit (ce qui est le cas des fonctions de l'API Windows qui ont une version ascii avec A et une unicode avec U je crois).


Merci gilou.

gilou a écrit :


En plus, pourquoi faire compliqué?
A+,


Hum ! C'est l'exemple... !  :??:

Reply

Marsh Posté le 16-11-2011 à 14:35:47    

J'ai pas eu le temps de poster le code que je pensais être le bon, mais je suppose que tu fais ceci:

Code :
  1. --
  2. --
  3. with Interfaces.C;
  4. with Ada.Unchecked_Conversion;
  5. with System;
  6. use System;
  7. package body Pp.Pp_Io is
  8.  
  9.   use Interfaces, Interfaces.C;
  10.  
  11.   type HANDLE is new Unsigned_32;
  12.   function LoadLibrary (lpFileName : char_array) return HANDLE;
  13.   pragma Import (stdcall, LoadLibrary, "LoadLibrary", "_LoadLibraryA@4" );
  14.  
  15.   function GetProcAddress (hModule : HANDLE; lpProcName : char_array)
  16.      return Address;
  17.   pragma Import (stdcall, GetProcAddress, "GetProcAddress", "_GetProcAddress@8" );
  18.  
  19.   type Out32_Type is access procedure (Port_Address : in C.Short;
  20.                                        Data : in C.Short);  
  21.   type Inp32_Type is access function (Port_Address : in C.Short) return C.Short;
  22.  
  23.   pragma Convention (Stdcall, Out32_Type);
  24.   pragma Convention (Stdcall, Inp32_Type);
  25.   function To_Out32_Type is new Ada.Unchecked_Conversion (Address, Out32_Type);
  26.   function To_Inp32_Type is new Ada.Unchecked_Conversion (Address, Inp32_Type);
  27.  
  28.   Library : HANDLE  := LoadLibrary (To_C ("inpout32" ));
  29.   Out_Pointer : Address := GetProcAddress (Library, To_C ("Out32" ));
  30.   Inp_Pointer : Address := GetProcAddress (Library, To_C ("Inp32" ));
  31.  
  32.   procedure Put(Msg : in Message_Type; Value : in Unsigned_8) is
  33.  
  34.      
  35.   begin
  36.      To_Out32_Type(Out_Pointer) (C.short(LP+Message_Type'Pos(Msg)), C.Short(Value));
  37.   end Put;
  38.  
  39.   procedure Get(Msg : in Message_Type; Value : out Unsigned_8) is
  40.  
  41.   begin
  42.    Value := Unsigned_8(To_Inp32_Type (Inp_Pointer)(C.short(LP+Message_Type'Pos(Msg))));
  43.   end Get;
  44. end Pp.Pp_Io;


 
>> En plus, pourquoi faire compliqué?  
Je pensais que le pragma Import (...) te permettais d’appeler directement la fonction de inpout32.dll sans avoir a faire toute la machinerie du loadLibrary
mais on dirait que non.
Ce qui est pas explicite ici:
pragma Import (stdcall, GetProcAddress, "GetProcAddress", "_GetProcAddress@8" );
c'est ou la fonction _GetProcAddress@8 est récupérée (ie dans quelle librairie système de Windows). Surprenant de la part d'un langage qui explicite en général tout.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 16-11-2011 à 14:37:16    

Il faut que ce soit exactement comme dans le .def (c'est à ça qu'il sert essentiellement).
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 16-11-2011 à 15:26:06    

gilou a écrit :


Je pensais que le pragma Import (...) te permettais d’appeler directement la fonction de inpout32.dll sans avoir a faire toute la machinerie du loadLibrary
mais on dirait que non.
Ce qui est pas explicite ici:
pragma Import (stdcall, GetProcAddress, "GetProcAddress", "_GetProcAddress@8" );
c'est ou la fonction _GetProcAddress@8 est récupérée (ie dans quelle librairie système de Windows). Surprenant de la part d'un langage qui explicite en général tout.
A+,


 
 
 
C'est ce que j'avais fait au début, mais effectivement ça marche pas.

Reply

Marsh Posté le 16-11-2011 à 20:02:15    


 
 
 
Comme je charge déjà une dll C++ avec Ada, je vais charger kernel32 avec C pour faire une simple bibliothèque C et faire import de cette dernière avec Ada.
 
Donc, je vais tester ton code de chargement de dll.
 
Je pense y arriver dans les prochaines minutes.


Message édité par Profil supprimé le 16-11-2011 à 20:03:20
Reply

Marsh Posté le 17-11-2011 à 16:40:40    

Je vois ceci un peu tard.
J'ai déjà répondu ailleurs à Jovalise, ma réponse est pour ceux qui liront ce topic dans le futur.
Inutile de charger kernel32, il est toujours chargé en mémoire puisque c'est un composant sans lequel windows ne fonctionnerait pas.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed