Commençons par ce qu'il y avait avant :
L’environnement s’appelait OPM
la règle était simple
Un membre source → un programme
(CRTRPGPGM)Pour utiliser un autre code → CALL
ILE
On peut, pas on doit ;-)
Lier (linker)
des morceaux de code entre eux
Le module est l'unité de compilation
(CRTRPGMOD, par ex)
-> Pour linker CRTPGM
![]()
Le code (sourceC par ex.) est dupliqué !
En cas de correction/modification
il faut « relinker » tous les programmes
contenant sourceC !
(et nous sommes mal outillés pour cela) !
On peut aussi :
Ignorer cette notion et faire de l'ILE
comme M. Jourdain fait de la prose (sans le savoir)
CRTBNDRPG
ILE
Permet aussi de faire des procédures :
- comme un sous-programme,
c'est dans le même source-comme un programme,
les variables ne sont pas partagées (locales)
elles apparaissent dans la liste d'invocation
(DSPJOB / opt 11)Particulièrement en C et en RPG
Exemple : Un Sous/pgm (BEGSR) devient une procédure (DCL-PROC)
Autre Exemple avec le projet JDBCR4
Enfin, nos recommandations
Externaliser (et donc rendre unique) le code
par les programmes de services
ce qui correspond plus à notre culture à tous
source du *SRVPGM
les fonctions peuvent s'appeler les une les autres
(sans EXPORT la fonction est purtement à usage interne)
Programmes de services
---------------------
Mise en placE
Pour le programme de service
- CRTRPGMOD
- CRTSRVPGM EXPORT(*ALL)
- ARCAD (par ex.)
- un composant RPGLE/*MODULE
puis
- un composant ILESRVPGMPour les programmes utilisant ce *SRVPGM
- CRTRPGMOD
- CRTPGM BNDSRVPGM(---) /* fastidieux ...*/
- ARCAD
- un composant RPGLE/*MODULE
puis
- un composant ILEPGM
Quelques recommandations
Utilisez les répertoires de liage
Créez un répertoire de liage « entreprise » (CRTBNDDIR votre-nom)
A chaque fois que vous créez un programme de service, enregistrez le (ADDBNDDIRE)
Compilez vos programmes avec BNDDIR :
ou mieux Ctl-opt BNDDIR(votre-nom) ; dans le source
WRKBDNDIRE pour voir le contenu actuel
(ici QC2LE utile pour nombre d'API, destinées à l'origine au langage C)
Utilisez le langage de liage
Créez un membre source par programme de service dans QSRVSRC
STRPGMEXP SIGNATURE('ma-signature-en-dur')
EXPORT symbol(routine1)
EXPORT symbol(routine2)
EXPORT symbol(routine3)
ENDPGMEXP
Si vous ajoutez une routine, ajoutez la en fin de liste :
STRPGMEXP SIGNATURE('ma-signature-en-dur')
EXPORT symbol(routine1)
EXPORT symbol(routine2)
EXPORT symbol(routine3)
EXPORT symbol(routine4)
ENDPGMEXP
NE CHANGEZ PAS LA SIGNATURE, sauf modification importante, vous seriez obligé de recompiler tous les programmes !
NE CHANGEZ PAS L'ORDRE, les programmes ne mémorisent pas qu'il doivent utiliser la routine qui se nomme « routine2 », mais la position de la routine (la n° 2)
Paramètre OVRSCOPE sur OVRDBF (par ex.) indique la portée de la substitution • *ACTGRPDFN, valable pour le groupe d'activation (uniquement) du pgm |
Paramètre OPNSCOPE sur OPNDBF, OPNQRYF, indique la portée d'une ouverture SHARE(*YES) • *ACTGRP, valable pour le groupe d'activation (uniquement) du pgm |
En effet, SQL fonctionne de la manière suivante : . première utilisation d'un fichier ou d'une table, il est ouvert puis fermé . dès la deuxième utilisation, il ne sera fermé que suivant ce paramètre |
Paramètre CMTSCOPE sur STRCMTCTL • *ACTGRP, transaction valide pour le groupe d'activation (uniquement) du pgm, |
Plusieurs valeurs possibles :
*DFTACTGRP, donné par DFTACTGRP(*YES)
C'est le cas des programmes RPG III
C'est le cas des programmes RPG IV, compilés par CRTBNDRPG
*NEW, donné par DFTACTGRP(*NO) ACTGRP(*NEW)Pour faire simple, tout fonctionne comme avant.
Pas toujours possible, DCL-PROC impose DFTACTGRP(*NO) !
Le groupe d'activation est créé à chaque appel (pour infos, cela permet la récursivité en RPG)
Le groupe d'activation est supprimé en fin de programme, toutes les ressources qui lui sont associées (fichiers ouverts, mémoire allouée)
sont récupérées à cette occasion : consommateur en mémoire.
UN_NOM, donné par DFTACGRP(*NO) ACTGRP(UN_NOM)
Le groupe d'activation est créé si besoin lors de l'appel
C'est vous qui décidez du moment de la récupération des ressources par RCLACTGRP
Évitez QILE, utilisé par tout le monde (les éditeurs, par ex.)
Le plus simple: *CALLER
Sur tous les programmes, sauf (quand vous serez prêts) sur le programme d’entrée ou vous indiquerez
*NEW, si vous ne voulez pas gérer les ressources
un_nom si vous voulez avoir la maîtrise de la gestion
des ressources (RCLACTGRP)
Enfin les groupes d'activation ont une influence sur la gestion des erreurs
Regardons comment fonctionne le système « d'habitude » ...
Si l'erreur n'est pas gérée, le système envoie un message "function check" |
Avec ILE
Si l'erreur n'est pas gérée, le système renvoie LA MEME ERREUR, au pgm précédent (pas à la procédure précédente) dans la liste d'invocation ("to percolate") à l'intérieur du groupe d'activation, on peut donc imaginer qu'un CLLE reçoivent RNXxxxx ou MCHxxxx jusqu'à la rencontre d'un pgm d'un autre groupe d'activation qui lui reçoit le message : CEE9901 "application ended". |
Condition Handler ?
Définie par l'API liable CEEHDLR, fait référence à une procédure liée (CEEHDLU annule cette déclaration)
La routine déclarée "hanlder" est appelée en cas d'erreur et peut indiquer un des codes suivants :
10 Ignorer et continuer (au resume cursor)
vous pouvez modifier le "resume cursor" avec l'API CEEMRCR, sinon l'appelant
Voir ce cours lié à la V3R10, pour plus de détail
la documentation dit la chose suivante :
la commande RCLRSC n'a de portée qu'à l'intérieur du groupe d'activation par défaut.
pour un groupe d'activation nommé, il faut utiliser RCLACTGRP
un programme ne peut pas passer la commande RCLACTGRP pour le groupe auquel il appartient (contrairement à RCLRSC)
Si vous mettez vos programmes de services dans DFTACTGRP , et que ces derniers utilisent des déclarations de fichiers globales (Dcl-F hors procédure)
La commande RCLSRC ferme bien les fichiers, mais ne désactive pas les *SRVPGM
Au prochain appel du programme de service ce dernier est persuadé que les fichiers sont toujours ouverts (et ce n'est plus le cas)
Vous recevrez MCH3401 "Tentative d'accès à tout ou partie d'un objet qui n'existe plus."
La solution la plus prudente est désormais de déclarer vos fichiers par des déclarations locales
Chaque procédure est autonome, quant à l'utilisation du fichier Cela permet d'avoir des utilisations différentes (INPUT sur l'une, UPDATE sur l'autre, etc...) |