Interface avec d`autre langages

Transcription

Interface avec d`autre langages
Séance 11 Interface avec d’autre langages Objectifs : Être en mesure de comprendre comment un programme Ada peut s’interfacer avec des bibliothèques écrites en d’autre langages. ü Comprendre les conventions pour la communication avec d’autres langages. ü Explorer la programmation bas niveau pour accéder directement au matériel.
ü 1 © 2008 Ingénierie du logiciel avec ADA – N.KERZAZI Interface avec d’autre langages
¡ L'accès au langage machine et à d'autres langages est nécessaire pour l Des questions d'efficacité l Faire faire certaines opérations par le matériel l Pouvoir communiquer avec les logiciels existants. 2 Conventions ¡ Les interfaces avec d’autres langages ne sont pas optimisées pour un programme particulier mais pour des conventions. l Convention pour la représentation des types. l Convention pour l’utilisation de la mémoire et des registres. l État de la mémoire pendant et après l’appel d’une procédure. 3 © 2008 Ingénierie du logiciel avec ADA – N.KERZAZI
Exemple ¡ On veut communiquer avec une bibliothèque écrite en «C» qui gère la souris. En intercepte le clique de la souris pour appeler une procédure en Ada Type Reponse is access procedure (D:in Data); Pragma Conversion (C, Reponse); Procedure Set_Click (P: in Reponse); Pragma Import (C, Set_Click); ‐‐ indique que le corps de Set_Click est externe au programme Ada Procedure Action (D: in Data) is separate; Pragma Conversion (C, Action); … Set_Click (Action’Access); ‐‐ appel de la fonction C avec l’adresse de notre procédure l Ada comme paramètre. 4 © 2008 Ingénierie du logiciel avec ADA – N.KERZAZI
SOUS­PROGRAMMES EN D'AUTRES LANGAGES
¡ On peut faire appel à un sous‐programme écrit en un autre langage en : l écrivant une spécification en Ada, l en utilisant le pragma Import dans le corps. Certains fabricants ont ajouté un pragma pour résoudre l'ambiguïté des noms à l'édition de liens. package Fort_Lib is function Sqrt ( X : Float ) return Float; function Exp ( X : Float ) return Float; private pragma Import ( Fortran, Sqrt, "SQRT"); pragma Import ( Fortran, Exp, "EXP" ); end Fort_Lib; 5 Interface avec d’autre langages
¡ Ada fournit les paquetages l Interfaces.C ¡ Interfaces.C.Strings Interfaces.FORTRAN l Interfaces.COBOL et les pragma l ¡ l l l pragma Import ( Langage, Nom_En_Ada, Nom_Langage, Nom_Externe); pragma Export ( Langage, Nom_En_Ada, Nom_Langage, Nom_Externe); pragma Convention (Langage, Objet); 6 Interface avec d’autre langages
¡ Interfaçage direct (appel à une fonction C); with Interfaces.C ; with System ; package gl is type GLfloat is new Interfaces.C.C_Float ; subtype Float is GLfloat ; type GLenum is new Interfaces.C.Unsigned ; subtype Enum is GLenum ; type GLboolean subtype Boolean is new Interfaces.C.Unsigned_Char ; is GLboolean; type GLbitfield subtype Bitfield is new Interfaces.C.Unsigned ; is GLbitfield; type GLbyte is new Interfaces.C.Signed_Char ; subtype Byte is GLbyte; type GLshort is new Interfaces.C.Short ; subtype Shortis GLshort; ...... end gl; 7 Interface avec d’autre langages
¡ Interfaçage direct (appel à une fonction C); with gl; with System ; package glu is function gluUnProject ( Winx, Winy, Winz: gl.GLdouble; Modelmatrix : System.Address; Projmatrix : System.Address; Viewport : System.Address; Objx, Objy, Objz : Gl.Gldoublestar) return gl.GLint; pragma Import ( C, GluUnProject , "gluUnProject"); function UnProject ( Winx, Winy, Winz : gl.GLdouble; Modelmatrix : System.Address; Projmatrix : System.Address; Viewport : System.Address; Objx, Objy, Objz : gl.GLdoublestar) return gl.GLint renames gluUnProject ...... end Glu; 8 Interface avec d’autre langages
¡ Interfaçage indirect (en bulle); package glut is procedure InitWindowSize( Width : in Integer := 300 ; Height : in Integer := 300); procedure InitWindowPosition( X : in Integer := ‐1 ; Y : in Integer := ‐1); end glut; with gl; package body glut is procedure InitWindowSize( Width : in Integer := 300 ; Height : in Integer := 300) is procedure glutInitWindowSize(Width, Height : in GLint); pragma Import (C, glutInitWindowSize, "glutInitWindowSize"); begin glutInitWindowSize (GLint(Width), GLint(Height) ); end InitWindowSize ; procedure InitWindowPosition( X : in Integer := ‐1 ; Y : in Integer := ‐1) is procedure glutInitWindowPosition(X, Y : in Glint); pragma Import (C, glutInitWindowPosition, "glutInitWindowPosition"); begin glutInitWindowPosition (GLint(X), GLint( Y )); end InitWindowPosition ; end glut; 9 Interface avec d’autre langages
¡ Convention (pragma Convention) Matrix : array ( Integer range 1 .. 10, Integer range 1 .. 10) of Float; pragma Convention ( Fortran, Matrix); ¡ Appel de fonctions par un programme C (fonction de rappel) procedure MyReshape (W, H : in Glsizei); pragma Convention (Stdcall, MyReshape); procedure Display; pragma Convention (Stdcall, Display); glutReshapeFunc (MyReshape'Unrestricted_Access); glutMainLoop (Display'Unrestricted_Access); 10 Interface avec d’autre langages
¡ Programme dont le programme principal est en C. l Main program (m.c) void main() { adainit(); Header(); adafinal(); } Ada subroutine (header.adb) with Text_Io; use Text_Io; procedure Header is begin Put_Line ("Header"); end Header ; pragma Export (C, Header, "Header"); l 11 Programme principal en C
/* programme en C */ extern int F_en_C ( int Par ); main () { int P1; P1 = 2; P1 = F_En_C ( P1); printf ( " Valeur de P1 %d\n", P1); } 12 Appel depuis le programme Ada
­­ Fichier P_Interface ­­ Spécification du paquetage Ada contenant la fonction with Interfaces.C ; use Interfaces.C; package P_Interface is function F ( Par : Interfaces.C.Int ) return Interfaces.C.Int ; pragma Import ( C, F, "F_En_C"); end P_Interface; package body P_Interface is function F ( Par : Interfaces.C.Int ) return Interfaces.C.Int is begin return Interfaces.C.Int ( Integer ( Par) * 2 ); end F; end P_Interface; 13 Gestion de dispositifs
¡ ¡ ¡ ¡ Les E/S peuvent être considérées comme des processus externes. La façon la plus simple de traiter des E/S est le "polling", mais la plupart des périphériques utilisent des interruptions. Une interruptions en Ada peut être traitée comme une entrée d'une tâche. Exemple: (Ada 83) l Supposons qu'un ordinateur à l'intérieur d'une machine à électro‐cardiogramme reçoit un vecteur d'interruption 10H à chaque battement du cœur. On peut écrire une fonction qui donne le nombre de battements depuis le dernier appel. 14 Gestion de dispositifs(Suite)
package Battement_Du_Cœur is function Nouveaux_Battements return Natural; end Battement_Du_Coeur; with System: ‐‐ pour utiliser ADDRESS package body Battement_Du_Cœur is task Gestion_Interruption_Battement is entry Interruption_Battement; entry Lire_Et_Restaurer_Compteur (Nombre_D_Interruption : out Natural); for Interruption_Battement’Address use System.Storage_Elements.To_Address(16#10# ); ‐‐for Interruption_Battement’Address use ‐‐System.Interrupts.Reference(Ada.Interrupts.Names.Capteur_A); end Gestion_Interruption_Battement; function Nouveaux_Battements return Natural is Résultat : Natural; begin Gestion_Interruption_Battement.Lire_Et_Restaurer_Compteur (Résultat); return Résultat; end Nouveaux_Battements; 15 Gestion de dispositifs (Suite)
task body Gestion_Interruption_Battement is Compte_Non_Rapporté : Natural := 0; begin loop select accept Interruption_Battement; Compte_Non_Rapporté := Compte_Non_Rapporté + 1; or accept Lire_Et_Restaurer_Compteur ( Nombre_D_Interruption : out Natural) do Nombre_D_Interruption := Compte_Non_Rapporté; end Lire_Et_Restaurer_Compteur; Compte_Non_Rapporté := 0; end select; end loop; end Gestion_Interruption_Battement; end Battement_Du_Coeur; 16 Programme de gestion de périphériques ( analogue­digital)
package Adc_Device_Driver is Max_Measure : constant := (2**16)‐1; type Channel is range 0 .. 63; subtype Measurement is Integer range 0 .. Max_Measure; procedure Read(Ch: Channel; M : out Measurement); ‐‐ potentially blocking Conversion_Error : exception; private for Channel'Size use 6; ‐‐ indicates that six bits only must be used end Adc_Device_Driver; 17 Programme de gestion de périphériques ( analogue­digital) Ie Channe l Ad _Sta rt Unused
Error Word : constant := 2; ‐‐ bytes in word type Flag is (Down, Set); Done with Ada.Interrupts.Names; use Ada.Interrupts; with System; use System; with System.Storage_Elements; package body Adc_Device_Driver is Bits_In_Word : constant := 16; ‐‐ bits type Control_Register is 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 0 record Ad_Start : Flag; Ie : Flag; Done : Flag; Ch : Channel; Error : Flag; end record; for Control_Register'Size use Bits_In_Word; ‐‐ the register is 16 bits long for Control_Register'Alignment use Word; ‐‐ on a word boundary 18 Programme de gestion de périphériques ( analogue­digital)
type Data_Register is range 0 .. Max_Measure; for Data_Register'Size use Bits_In_Word; ‐‐ the register is 16 bits long Contr_Reg_Addr : constant System.Address := System.Storage_Elements.To_Address(8#150002#); Data_Reg_Addr : constant System.Address := System.Storage_Elements.To_Address(8#150000#); Adc_Priority : constant Interrupt_Priority := Interrupt_Priority’First; Control_Reg : aliased Control_Register; for Control_Reg'Address use Contr_Reg_Addr; ‐‐ specifies the address of the control register Data_Reg : aliased Data_Register; for Data_Reg'Address use Data_Reg_Addr; ‐‐ specifies the address of the data register 19 Programme de gestion de périphériques ( analogue­digital)
protected type Interrupt_Interface( Int_Id : Interrupt_Id; Cr : access Control_Register; Dr : access Data_Register) is entry Read (Chan : Channel; M : out Measurement); private entry Done (Chan : Channel; M : out Measurement); procedure Handler; pragma Attach_Handler(Handler, Int_Id); pragma Interrupt_Priority(Adc_Priority); Interrupt_Occurred : Boolean := False; Next_Request : Boolean := True; end Interrupt_Interface; Adc_Interface : Interrupt_Interface(Names.Adc, Control_Reg'access, Data_Reg'access); ‐‐this assumes that 'Adcl is registered as an ‐‐Interrupt_Id in Ada.Interrupts.Names 20 Programme de gestion de périphériques ( analogue­digital)
protected body Interrupt_Interface is entry Read (Chan : Channel; M : out Measurement) when Next_Request is Shadow_Register : Control_Register; begin Shadow_Register := ( Ad_Start => Set, Ie => Set, Done => Down, Ch => Chan, Error => Down ); Cr.all := Shadow_Register; Interrupt_Occurred := False; Next_Request := False; requeue Done; end Read; procedure Handler is begin Interrupt_Occurred := True; end Handler; 21 Programme de gestion de périphériques ( analogue­digital)
entry Done (Chan : Channel; M : out Measurement) when Interrupt_Occurred is begin Next_Request := True; if Cr.Done = Set and Cr.Error = Down then M := Measurement(Dr.all); else raise Conversion_Error; end if; end Done; end Interrupt_Interface; procedure Read (Ch : Channel; M : out Measurement) is begin for I in 1 .. 3 loop begin Adc_Interface.Read(Ch, M); return; exception when Conversion_Error => null; end; end loop; raise Conversion_Error; end Read; end Adc_Device_Driver; 22 Accès aux arguments de la ligne de commande with Ada.Command_Line, Ada.Text_IO; use Ada.Command_Line, Ada.Text_IO; procedure Commande is begin Put_Line ( "Mon nom est " & Command_Name & " J'ai " & Integer'Image ( Argument_Count) & " arguments qui sont"); for i in 1 .. Argument_Count loop Put_Line (" " & Argument(I)); end loop; end Commande; N:\Ada\ogl-glut-demo\glut>commande.exe
Louis
Granger
Mon nom est commande.exe J'ai
2 arguments qui sont
Louis
Granger
23 Insertion d’instructions machine
¡ Chaque instruction machine apparaît sous forme d'un agrégat d'un type article qui définit l'introduction correspondante. Le type doit être défini dans la bibliothèque prédéfinie MACHINE_CODE. with Machine_Code; M : Masque; procedure Positionner_Masque; pragma Inline (Positionner_Masque); procedure Positionner_Masque is use Machine_Code; begin Asm ("fsinx %1 %0", My_Float'Asm_Output ("=f", result), My_Float'Asm_Input ("f", angle)); end Positionner_Masque; 24 

Documents pareils