Les appels de pgm + ILE

BoTTom |    Changer de couleur
 
Sur AS/400, un programme de n'importe quel langage peut appeler un pgm
 de n'importe quel langage de manière dynamique.
 
 Ceci est particulièrement vrai pour RPG,RPGIV, COBOL et CL.
 
 Le lien avec le pgm appelé est dynamique, c'est à dire :
 
         - que le programme appelant ne le connaît pas avant l'exécution.
 
         - le pgm appelé est recherché quand l'ordre CALL est rencontré.
 
           + adressage du pgm
 
           + vérification des droits
 
           + chargement en mémoire, réservation d'espace pour les variables.
 
           + seules les variables passées en tant que paramètres sont
                                                                partagées.
 
         - retour à l'instruction qui suit le CALL à la fin du pgm appelé.


|    Changer de couleur
  pgm appelant (A)
 
 
 
 
        ........................
        : mémoire              :
        : nocli : 00006        :
        : nomcli: Durant       :
        :----------------------:
        :                      :
        :  CALL PGMB           :
        :  PARM      NOCLI     :
        :                      :
        :                      :
        :                      :
        :                      :
        :                      :
        :......................:
 
 
 


|    Changer de couleur
  pgm appelant (A)
                                            Pgm B addressé (suivant *LIBL)
                                            chargé en mémoire si les droits
                                             sont corrects.
                                           ...........................
        ........................           : mémoire                 :
        : mémoire              :           :                         :
        : nocli : 00006        :           : nomcli:                 :
        : nomcli: Durant       :           : nocli.adr :             :
        :----------------------:           :-------------------------:
        :                      :           : *ENTRY  PLIST           :
        :  CALL  PGMB          :           :         PARM       nocli:
        :  PARM          NOCLI :           :                         :
        :                      :           : (LINKAGE SECTION        :
        :                      :           :          en cobol)      :
        :                      :           :                         :
        :                      :           :                         :
        :                      :           :                         :
        :......................:           :                         :
                                           :                         :
                                           :.........................:
                                                     pgm appelé (B)


|    Changer de couleur
  pgm appelant (A)
                                            Pgm B reçoit l'adresse
                                             du paramètre et non sa valeur.
 
                                           ...........................
        ........................           : mémoire                 :
        : mémoire              :           :                         :
 12345> : nocli : 00006        :           : nomcli:                 :
        : nomcli: Durant       :    /------> nocli.adr : x'12345'    :
        :----------------------:  /        :-------------------------:
        :                      :/          : *ENTRY  PLIST           :
        :  CALL PGMB          /:           :         PARM       nocli:
        :  PARM      NOCLI  /  :           :                         :
        :                      :           :                         :
        :                      :           :                         :
        :                      :           :                         :
        :                      :           :                         :
        :                      :           :                         :
        :......................:           :                         :
                                           :                         :
                                           :.........................:
                                                     pgm appelé (B)


|    Changer de couleur
  pgm appelant (A)
                                            Il travaille donc sur la mémoire
                                             du pgm appelant.
 
                                           ...........................
        ........................           : mémoire                 :
        : mémoire              :           :                         :
 12345> : nocli : 00001 <----\ :           : nomcli:                 :
        : nomcli: Durant       \           : nocli.adr : x'12345'    :
        :----------------------: \         :-------------------------:
        :                      :   \       : *ENTRY  PLIST           :
        :  CALL PGMB           :     \     :         PARM       nocli:
        :  PARM      NOCLI     :       \   :                         :
        :                      :         \ :                         :
        :                      :           \                         :
        :                      :           : \                       :
        :                      :           :   \---- eval NOCLI = 1  :
        :                      :           :                         :
        :......................:           :                         :
                                           :                         :
                                           :.........................:
                                                     pgm appelé (B)


|    Changer de couleur
  pgm appelant (A)
                                            UNIQUEMENT pour les paramètres
                                             reçus.
 
                                           ...........................
        ........................           : mémoire                 :
        : mémoire              :           :                         :
 ###### : nocli : 00001        :           : nomcli: Dupont' <----------|
        : nomcli: Durant       :           : nocli.adr : x'12345'    :  |
        :----------------------:           :-------------------------:  |
        :                      :           : *ENTRY  PLIST           :  |
        :  CALL PGMB           :           :         PARM       nocli:  |
        :  PARM      NOCLI     :           :                         :  |
        :                      :           :                         :  |
        :                      :           :                         :  |
        :                      :           :                         :  |
        :                      :           :         eval NOCLI = 1  :  |
        :                      :           :         eval NOMCLI   -----|
        :......................:           :               = 'Dupont':
                                           :                         :
                                           :.........................:
                                                     pgm appelé (B)


|    Changer de couleur
  pgm appelant (A)
                                            A la fin du pgm appelé,
                                             retour à l'instruction qui suit
                                             le CALL.
                                           ...........................
        ........................           : mémoire                 :
        : mémoire              :           :                         :
 nocli  : nocli : 00001        :           : nomcli: Dupont'         :
  = 1.  : nomcli: Durant       :           : nocli.adr : x'12345'    :
        :----------------------:           :-------------------------:
        :                      :           : *ENTRY  PLIST           :
        :  CALL PGMB           :           :         PARM       nocli:
        :  PARM      NOCLI     :           :                         :
        :  ....   <-------------\          :                         :
        :  ....                :  \        :                         :
        :                      :    \      :                         :
        :                      :      \    :         eval NOCLI = 1  :
        :                      :        \  :         eval NOMCLI   --:
        :......................:         \ :               = 'Dupont':
                                           \         eval *inlr=*on  :
                                           :.........................:
                                                     pgm appelé (B)


|    Changer de couleur
 
  Le pgm appelé peut rendre la main à l'appelant sans pour autant être
   désactivé.
 
   en RPG   : RETURN
 
   en COBOL : EXIT PROGRAM.
 
              ATTENTION: ne fonctionne que si le pgm appelant est un COBOL.
 
                         GOBACK en cas de doute.
 
                         ou passer par un pgm COBOL "intermédiaire".
 
  en CL     : cela est malheureusement impossible (RETURN = ENDPGM)
 
              [si cela est possible faire en sorte que ce soit le pgm CL
                qui appelle (d'entrée de jeu).]
 
 
 
 


|    Changer de couleur
 
 Si le pgm n'est pas désactivé:
 
  toute la phase de chargement est inhibée.
 
  sa mémoire reste intacte (telle quelle lors du RETURN/EXIT PROGRAM)
 
  il reste positionné sur ces fichiers (lecture séquentielle)
 
  en RPG , le cycle ne passe pas par la phase d'ouverture des fichiers.
 
  en COBOL, conditionner OPEN avec un flag (puisque la mémoire est intacte)
 
 Pour désactiver les pgms appelés (et fermer les fichiers)
 
      utiliser le pgm suivant:
 
 "MENAGE" (CLP)  PGM                       ################################ 
                 RCLRSC lvl(*CALLER)       #  RCLACTGRP si DFTACTGRP(*no) # 
                 ENDPGM                    ################################ 
 
      ou passez directement la commande sur la ligne de commandes


|    Changer de couleur
 
           si les deux programmes utilisent des fichiers écran (DSPF)
 
              les fichiers écrans sont suspendus et le système peut être
              "perdu" lors d'un réaffichage.
 
           Penser alors à indiquer RSTDSP(*YES) sur les commandes
 
                          CRTDSPF  ou CHGDSPF
 
           Afin que le système sauvegarde la totalité de l'image avant
            suspension du DSPF et la restaure avant réaffichage.
 
 
           Cette manipulation n'est, bien entendu, pas gratuite,
            particulièrement avec des terminaux éloignés.
 
           C'est pourquoi la valeur par défaut est à *NO sur la commande
            de création.
 
 
 


|    Changer de couleur
  RPG-IV propose une nouvelle manière de gérer les appels en format libre :
 
   1/ déclaration préalable du programme appellé et des paramètres
      ==> un PROTOTYPE (type de déclaration PR)
 
       DProgrammeB       PR                  EXTPGM('PGMB')
       D                                6  0
  ou
        dcl-PR ProgrammeB EXTPGM(PGMB');
          *N char(6);
        end-pr;
 
      Sont définis :
 
       + le nom du programme, le nom externe(réel) pouvant être différent.
       + les paramètres transmis (nombre et types)
 
         les paramètres transmis supportent alors des mots-clés, comme :
 
         CONST ce paramètre peut ne PAS etre une variable(constante,calcul)
         VALUE passage de parmètre par valeur (pas de valeur retour)
          et d'autres...


|    Changer de couleur
 
      L'appel lui-même en spécif C ou en FORMAT LIBRE
 
      ==> nouveau code opération CALLP. (faculatif en format libre)
 
      /free
        ProgammeB(nocli) ;
      /end-free
 
   2/ la réception des paramètres peut elle même être réalisée
 
      a/ soit, comme avant (*ENTRY PLIST)
 
      b/ ou en spécif D, avec protoype ET une interface de procédure ( PI )
 
       DProgrammeB       PR                  EXTPGM('PGMB')
       D                                6  0
       DProgrammeB       PI
       D nocli                          6  0
 
      c/ avec DCL-PI en free-form RPG (voir exemple plus loin)
 


|    Changer de couleur
 
 Vous pouvez aussi appeler des procédures, car RPG-IV admet maintenant
  plusieurs procédures (au sens ILE) par source.
 
  Une procédure ressemble à :
 
    - un sous-programme :
 
            elle est codée dans le même source
            elle a des temps de réponse proches
            elle "voit" les fichiers ouverts par le pgm principal.
 
   - à un programme indépendant :
 
            elle occupe un niveau d'invocation
                        (influence sur la gestion des erreurs)
            elle ne connait que ces propres variables.
 
   - ni à l'un, ni à l'autre, car :
 
            vous choisissez si elle utilisable par un autre pgm.
            elle peut se présenter sous la forme d'une fonction


|    Changer de couleur
 
 Déclaration d'une procédure ou d'une fonction   [OBLIGATOIRE]
 
 la délaration se fait par le biais d'un prototype comme vu plus haut.
 
 Définition d'une procédure ou d'une fonction 
 
 Une nouvelle spécif "P" pour définir le début et la fin de la fonction
                                              (proche de BEGSR / ENDSR)
 
 EXPORT autorise l'utilisation de cette procédure par des modules externes
        (sinon cette procédure est privée c'est à dire utilisable
          uniquement dans le même source)
 
 Des Spécifs D  pour définir les paramètres recus (PI à la place de PR)
 
     Et le système VERIFIE que l'interface (PI) est indentique au prototype
 
 Des Spécifs D  pour définir les variables locales
 
 des ordres de traitement (spécif C ou /free)
 


|    Changer de couleur
                  structure générale d'un pgm RPG-IV :  
 
H  Spécif H générale       |contient NOMAIN s'il n'y a pas de pgm principal
F  Déclaration de fichiers |(ouvertures globales)
D  variables globales      |
D proc1           PR       | prototype procédure 1
D proc2           PR       | prototype procédure 2
I  variables des fichiers  | (globales)
C  traitement              | programme principal
O  sorties                 | sorties du programme principal
 
P proc1           B       -|
D                 PI       | définition de l'interface
D                          | variables locales
C                          | traitement
P                 E       -|
 
P proc2           B       -|
D                 PI       |  2ème procédure (idem)
D                          |
C                          |
P                 E       -|


|    Changer de couleur
 
 Et tout cela nous ammène vers les fonctions,
 
    une fonction est une forme particulière de procédure qui :
 
    ° retourne une valeur (la définition est donnée sur les lignes PR ET PI)
 
    ° peut donc directement être utilisée en lieu et place de la valeur
       qu'elle retourne (comme une fonction intégrée %xxx)
 
    ° DOIT être déclarée par un prototype (CALL|CALLP sont invalides)
 
 Le prototype devant être déclaré aussi bien dans le source écrivant la
  fonction, que dans tous les sources qui l'utilisent, il est conseillé
  de placer le prototype  dans un source à part et de copier ce source
  par
 
      /COPY fichier,membre
 
 On rejoint ansi une philosophie "langage C" ou toutes les fonctions
  sont externes au langage et ou il faut copier les fichiers de déclaration
  par les fameux "include stdio.h", etc...


|    Changer de couleur
 Exemple: 
                                     /-- cette fonction retourne une DATE.
                                    /
DFindemois        PR              D   
D                                 D   DATFMT(*ISO)
 
 
P Findemois       B
 * Définition de l'Interface de procédure  (PI)
 *  doit être conforme avec le prototype (vérifié à la compilation)
D                 PI              D   
D Datein                          D   DATFMT(*ISO)
 * variables locales
D  Wdate          S               D
  //exemple : 15 avril + 1 mois => 15 Mai / -15 jours => 30 Avril
 /free
   wdate = DATEIN + %MONTHS(1);
   wdate = wdate - %days(%SUBDT(wdate:*D))
   return wdate;
 /end-free
P Findemois       E
 


|    Changer de couleur
 Exemple (en free_from): 
 
                        /-- cette fonction retourne une DATE.
    dcl-PR Findemois DATE;
      *N DATE(*ISO);
    end-pr;
 
    dcl-proc Findemois;
     // Définition de l'Interface de procédure  (DCL-PI)
     // doit être conforme avec le prototype (vérifié à la compilation)
     dcl-PI *N DATE;
        dateIN DATE(*ISO);
     end-pi;
     // variables locales;
      dcl-s Wdate  DATE;
 
       //exemple : 15 avril + 1 mois => 15 Mai / -15 jours => 30 Avril
        wdate = DATIN + %MONTHS(1);
        wdate = wdate - %days(%SUBDT(wdate:*D));
        return wdate;
 
    end-proc;


|    Changer de couleur
 
 
 les Appels peuvent être aussi statiques (==> phase de liage)
 
 
LIEN STATIQUE:
 
 
unité d'utilisation = procédure  - partie de code à point d'entrée unique
                                 - réalise une fonction, une action
                                 - n'est PAS un objet OS/400
 
                         V3r10     + RPG      : une procédure par source
                         V3r60                : x procédures par source
                                   + COBOL    : x procédures  par source
                                   + C/400    : x procédure(s) par source
 
Appel d'une procédure = "call bound"
                (CALLB en RPG, CALL PROCEDURE en COBOL, CALLPRC en CL)
 
les procédures apparaissent dans la liste d'invocation (DSPJOB/opt 11)
 


|    Changer de couleur
 
unité de compilation = module    - résultat d'une compil.
                                 (base = un membre source)
                                 - contient une ou plusieurs procédures
                                 (code compilé)
                                 - c'est un objet OS/400 *MODULE 
                                 - n'est PAS EXECUTABLE
        commande  CRTRPGMOD 
 
unité d'exécution = programme    - objet de type *PGM
                                 - lien dynamique (appel par CALL)
        commande  CRTPGM 
 
 
AVANTAGES:
          - meilleures performances
          - meilleure intégration de langages différents
          - introduction des fonctions en C ET RPG-IV
 
INCONVENIENTS:
          - duplication du code = moins de souplesse, duplication en mémoire
                                = maintenance des applicatifs compliquée !!!


|    Changer de couleur
 
                         CRTxxxMOD           CRTPGM PGM(PROG01) +
                                                    MODULE(A B C)
 ..fichier source............
 : .RPG...................  :
 : :                     :  :   ############### 
 : :        membre A     :  :-> # MODULE A    # --  ####################### 
 : :.....................:  :   ###############  !  # PROG01 : *PGM       # 
 :                          :                    !  ####################### 
 : .COBOL.................  :   ###############  !  #      #       #      # 
 : :        membre B     :  :-> # MODULE B    #   > #      #       # P1   # 
 : :.....................:  :   ###############  !  #  A   #   B   ######## 
 : .C.....................  :                    !  #      #       #      # 
 : : membre C | P1  | P2 :  :-> ###############  !  #      #       # P2   # 
 : :.....................:  :   # MOD.C P1 P2 # --  #      #       #      # 
 :..........................:   ###############     ####################### 
 
 
 
la création de PROG02 à partir des modules A,E,F,G entraînerait la
 duplication du module A dans cet autre programme.
 


|    Changer de couleur
 
 
    Pour diminuer les problèmes de duplication de code pour les procédures
     souvent utilisées, ILE introduit un nouveau type d'objet:  *SRVPGM 
     (programme de service,équivalent des DLL Windows ou OS/2)
 
 
    Objet contenant un ensemble de modules (donc de procédures)
 
 
    Le lien est fait par référence (dynamique) à l'appel du pgm principal,
     ensuite l'appel d'une procédure est statique.
 
 
 
    (les modules système sont des *SRVPGM = bibliothèques de fonctions)
 
 
 
 
 
 


|    Changer de couleur
 
*SRVPGM:
 
                         CRTxxxMOD           CRTSRVPGM SRVPGM(SRV01) +
                                                       MODULE(B C)
                                                       EXPORT(*ALL)
 
 ..fichier source............
 : .RPG...................  :
 : :                     :  :   ############### 
 : :        membre A     :  :-> # MODULE A    #                        
 : :.....................:  :   ############### 
 :                          :                              ################ 
 : .COBOL.................  :   ############### --         #       #      # 
 : :        membre B     :  :-> # MODULE B    #  !         #       # P1   # 
 : :.....................:  :   ###############   >        #   B   ######## 
 : .C.....................  :                    !         #       #      # 
 : : membre C | P1  | P2 :  :-> ###############  !         #       # P2   # 
 : :.....................:  :   # MOD.C P1 P2 # --         #       #      # 
 :..........................:   ###############            ################ 
 
 


|    Changer de couleur
 
*SRVPGM:
 
                         CRTxxxMOD           CRTPGM PGM(PROG01)
                                                    MODULE(A)
                                                    BNDSRVPGM(SRV01)
 
 ..fichier source............                             ################# 
 : .RPG...................  :                             # Prog01        # 
 : :                     :  :   ###############           # (ref : SRV01) # 
 : :        membre A     :  :-> # MODULE A    # ------>   ################# 
 : :.....................:  :   ###############              /
 :                          :                              ################ 
 : .COBOL.................  :   ###############            #       #      # 
 : :        membre B     :  :-> # MODULE B    #            #       # P1   # 
 : :.....................:  :   ###############            #   B   ######## 
 : .C.....................  :                              #       #      # 
 : : membre C | P1  | P2 :  :-> ###############            #       # P2   # 
 : :.....................:  :   # MOD.C P1 P2 #            #       #      # 
 :..........................:   ###############            ################ 
 
 


|    Changer de couleur
 
 On peut modifier un module dans un programme existant sans re-linker :
 
 
    UPDPGM  PGM(PROG01)  MODULE(A)
 
 
 
 On peut modifier un programme de service de la même manière  :
 
 
    UPDSRVPGM  SRVPGM(SRV01) MODULE(B)
 
 
 
 Attention, si l'on ajoute un module dans le programme de service il y a
  alors un contrôle (type level-check) avec les programmes qui utilisent.
 
 il faut recompiler les programmes
 
 
 


|    Changer de couleur
 
Pour faciliter le liage, il existe un nouveau type d'objet *BNDDIR 
(Binding directory) = répertoire de liage
 
Commandes associées : CRTBNDDIR          ADDBNDDIRE
                      DLT  "             RMV "  "
                      DSP  "             WRK "  "
                      WRK  "
 
Il référence un ensemble de modules et de pgms de service dont peut avoir
 besoin une application, évitant de lister tous les modules à lier.
 
Le programme de liage ira chercher dans cette "directory" toutes les
 références non résolues. (noms de modules et de fonctions non trouvés)
 
  ADDRDBDIRE REPERTOIRE SRV01
 
puis
 
  CRTPGM PGM(PROG01)
         MODULE(A)
         BNDDIR(REPERTOIRE)





©AF400