> Tech > Les prototypes RPG IV en 10 points clés

Les prototypes RPG IV en 10 points clés

Tech - Par iTPro.fr - Publié le 24 juin 2010
email

par Bryan Meyers
Utilisez les prototypes pour passer des paramètres intelligemment

Les prototypes
constituent l’une des nombreuses nouvelles fonctions, structures et
contraintes que le RPG IV a introduites dans le langage. Certains langages (et
plus particulièrement le C) supportent le prototypage depuis longtemps.
Toutefois, l’intérêt et l’objectif de ce mécanisme ne sont peut être pas évidents
pour les programmeurs RPG. Aussi, le présent article décrit-il les 10 points
les plus importants à  maîtriser pour tirer pleinement profit des prototypes.
Pour aller plus loin sur l’utilisation des prototypes en RPG IV, consultez
l’encadré “ Autres articles sur le sujet ”.
 

1.
Les prototypes permettent de définir les paramètres passés d’une procédure
à  une autre.

Un prototype est une définition
de l’interface d’appel entre procédures. Dans sa forme la plus simple, un
prototype présente trois éléments d’information à  un programme RPG :

  • Le
    nom de la procédure à  invoquer

  • Le
    nombre et les attributs des paramètres à  passer à  la procédure

  • Le
    cas échéant, le type et la taille des données constituant la valeur
    renvoyée par la procédure

En RPG IV, les prototypes sont écrits à  l’aide des spécifications de définition
(D), en utilisant le type de définition "PR". (La figure 1 présente
la structure d’une définition de prototype simple). Lors de la compilation, le
compilateur RPG/400 ILE utilise le prototype d’une part pour vérifier
l’interface d’appel entre procédures et d’autre part, pour s’assurer que la
procédure appelante passe les paramètres adéquats à  la procédure appelée.

 

2.
La définition d’un prototype ne nomme pas les paramètres et ne les déclare
pas non plus au programme.

Le prototype présenté
dans la figure 1 déclare une procédure nommée CalcPmt. Celle-ci renvoie un
nombre décimal (à  11 chiffres dont deux décimales) à  la procédure
appelante. Sur les lignes suivantes, le prototype énumère les attributs des
trois paramètres passés en entrée (LoanAmt, IntRate et Term) à  CalcPmt.

           
Il est possible d’affecter des noms aux paramètres, mais ces noms seront
purement et simplement informatifs. En effet, le programme doit malgré tout définir
l’ensemble des variables utilisées comme paramètres lors de l’appel de la procédure.
Le seul et unique intérêt de mentionner les paramètres dans un prototype est
de fournir au compilateur des informations concernant leurs attributs afin que
le compilateur puissent s’assurer de la cohérence des propriétés des paramètres
lorsqu’il compile cette procédure.

           
La définition d’un prototype doit être insérée aussi bien dans la
procédure appelante que dans la procédure appelée. Aussi est-il pratique
d’utiliser des membres /COPY pour sauvegarder les prototypes. Il peut s’avérer
utile d’exploiter les instructions de compilation conditionnelle pour que le
membre source de la procédure appelée fasse double emploi, comme le membre
/COPY lui-même. (Pour de plus amples informations sur cette technique,
consultez le “ Tip ” “ Utilisation des directives du compilateur
pour réutiliser le code RPG IV “ , NEWSMAGAZINE, février 1999, p68).
 

3. C’est
l’interface de procédure qui fournit la déclaration de paramètres à  la procédure.

L’interface d’une procédure
joue un rôle similaire à  celui du prototype. Toutefois, contrairement au
prototype, l’interface de la procédure déclare effectivement les variables qui
vont contenir les paramètres en entrée. A cet égard, l’interface d’une procédure
joue le même rôle qu’un *ENTRY PLIST dans un programme appelé.

           
Le code de l’interface de la procédure ne doit figurer que dans la procédure
appelée. La figure 2 présente l’interface d’une procédure correspondant au
prototype présenté dans la figure 1. Remarquez les similitudes frappantes
entre les deux définitions. Le type de définition utilisé pour l’interface de
la procédure est "PI" et le prototype utilise une définition
"PR". A part cela, les deux définitions sont identiques.

           
L’interface de la procédure définit les variables devant contenir les
paramètres. Ces variables représentent des variables locales et ne sont pas
visibles en dehors de la procédure dans laquelle elles ont été déclarées.
Dans l’interface de la procédure, le nom de la procédure est purement
informatif.

4. Utilisez CALLP
pour appeler une procédure prototypée, ou insérez la procédure dans une
expression si vous voulez utiliser une valeur en retour.

Lorsqu’on utilise
des appels prototypés, on peut invoquer des procédures dont le code est défini
dans le même module que l’appelant, ou des procédures exportées dont le code
est défini dans des modules distincts et liées au programme appelant, ou
encore des procédures liées sous la forme de programmes de service.

           
Généralement, une procédure appelée renvoie une valeur à  son
appelant. La procédure CalcPmt de la figure 3 par exemple, renvoie un montant
de paiement à  son appelant sous la forme d’un nombre décimal de 11 chiffres
dont deux décimales. CalcPmt retourne cette valeur en dehors du contexte des
variables. Aussi, il revient à  la procédure appelante d’affecter cette valeur
à  une variable. Pour les procédures de ce type, il est possible d’invoquer la
procédure simplement en incluant son nom de prototype dans une expression et de
passer les paramètres comme arguments au nom du prototype. La figure 4 illustre
un appel de la procédure CalcPmt.

Il se peut qu’une procédure ne renvoie aucune valeur à  son appelant.
Elle peut par exemple simplement se limiter à  mettre à  jour un fichier ou à 
appeler une API qui renvoie des informations via l’un de ses paramètres. Dans
ce cas de figure, on peut utiliser le code opération CALLP (Call Prototyped
Procedure or Program) pour appeler la procédure. La figure 5 présente la
syntaxe à  utiliser. L’utilisation de CALLP nécessite de déclarer un prototype
aussi bien dans la procédure appelante que dans la procédure appelée. De
plus, si la procédure appelée renvoie malgré tout une valeur, cette dernière
sera ignorée, même si le prototype définit une valeur de retour.
 

5. En plus des procédures,
il est possible de prototyper des appels de programmes.

Les prototypes ne se
limitent pas aux appels liés entre deux procédures d’un programme. En effet,
on peut également prototyper des appels à  des programmes externes. Cette
approche présente plusieurs avantages, dont la possibilité pour le compilateur
de vérifier les paramètres à  passer, de nouvelles méthodes de passage de
paramètres, une syntaxe d’appel au format libre, et moins de code à  générer
(aucune instruction PARM n’est nécessaire, par exemple). Les appels de
programmes prototypés sont plus particulièrement utiles pour invoquer des API
qui peuvent avoir des listes de paramètres complexes, ce qui est souvent source
d’erreurs.

           
La figure 6a présente un prototype d’appel simple de programme. Le
mot-clé EXTPGM indique le nom du programme à  appeler. Le nom du prototype ne
doit pas nécessairement correspondre au nom du programme. Lorsqu’on invoque
le programme, on utilise l’opération CALLP (comme le montre la figure 6b) et
comme nom de programme à  appeler, on précisera le nom du prototype et non le
nom du programme. Le programme appelé n’a pas besoin d’être inclus dans un
prototype.

           
Il est même possible de prototyper des appels aux programmes fournis par
IBM, comme QCMDEXC. La figure 7a présente un prototype pour QCMDEXC et la
figure 7b explique comment invoquer QCMDEXC dans un programme en lui passant,
dans une variable baptisée CmdStr, une valeur représentant une commande CL.
 

6. Les paramètres
peuvent être passés par référence, par valeur ou comme paramètres en
lecture seule.

L’un des
avantages du prototypage des appels de procédures est qu’on peut demander au
compilateur de vérifier l’interface d’appel entre deux procédures. Cela permet
aux programmeurs d’écrire des fonctions personnalisées en plus des fonctions
intégrées (ou BIF : built-in functions) fournies par IBM. Un autre
avantage est que les prototypes offrent de nouvelles options pour le passage des
paramètres.

  Le passage des paramètres par référence est la méthode utilisée
par défaut en RPG. Lorsqu’on passe un paramètre par référence, la procédure
appelée peut modifier le paramètre, et la procédure appelante prendra en
compte la valeur modifiée. En interne, le système passe un pointeur vers
l’emplacement mémoire contenant la valeur du paramètre, ce qui permet aussi
bien à  la procédure appelante qu’à  la procédure appelée de partager cette
information.

 En supportant le passage des paramètres par valeur, les
prototypes offrent la possibilité de protéger la zone de travail en mémoire
de la procédure appelante. En faisant précéder un paramètre du mot-clé
VALUE (comme on peut le voir sur la figure 1), cela indique aux deux procédures
de gérer chacune leur propre emplacement mémoire pour enregistrer la valeur du
paramètre et la procédure appelante ne voit aucune des modifications effectuées
sur le paramètre par la procédure appelée.

En plus de protéger l’emplacement mémoire de la procédure appelante,
le passage des paramètres par valeur permet également de passer des chaînes
de caractères et des expressions comme paramètres. La procédure appelante
passe simplement la valeur de la chaîne de caractères ou le résultat d’une
expression à  la procédure appelée. Enfin, passer des paramètres par valeur
offre une certaine latitude en ce qui concerne les attributs des paramètres. On
peut par exemple passer une information numérique sans avoir à  se demander si
les données sont pacquées ou zonées. 

Il n’est pas permis d’utiliser le mot-clé VALUE pour passer des paramètres
à  un programme externe. En effet, dans un appel à  un programme, les paramètres
doivent impérativement être passés par référence (pour cela, ne spécifiez
aucun mot-clé dans le prototype) ou en utilisant une troisième méthode appelée
read-only reference. Pour indiquer que l’on souhaite utiliser cette méthode,
il faut insérez le mot-clé CONST lors de la définition du paramètre dans le
prototype et dans l’interface de la procédure.

 Passez des paramètres par référence en mode lecture seule lorsque vous
êtes tenus de passer ces paramètres par référence (par exemple lorsque vous
invoquez un programme externe) mais que vous souhaitez jouir de la flexibilité
du passage des paramètres en tant que chaînes de caractères ou expressions.
Avec cette approche, le système peut copier la valeur du paramètre vers une
zone de travail temporaire, et passer ensuite un pointeur vers cette zone.
Assurez-vous que la procédure ou le programme appelé ne modifient pas la
valeur du paramètre. Certaines API ILE liables (comme les API CEE) nécessitent
que les paramètres soient passés par référence et en mode lecture seule.

7. Les valeurs
associées au mot-clé OPTIONS offrent une souplesse supplémentaire à  la définition
des paramètres.

Il est possible
d’associer une valeur au mot-clé OPTIONS afin d’apporter encore plus de
souplesse au passage de paramètres entre programmes ou procédures. En effet,
OPTIONS permet de :

  • Omettre
    un paramètre

  • Passer
    un paramètre d’une taille plus courte que ne l’indique le prototype

  • Passer
    une valeur spéciale *OMIT

Pour indiquer qu’un
paramètre est optionnel, insérez le mot-clé OPTIONS(*NOPASS) dans le
prototype avant la définition du paramètre concerné, et tous les paramètres
suivants (dès que l’on indique qu’un paramètre est optionnel, tous ceux qui
suivent doivent l’être aussi). Lorsqu’on invoque le programme ou la procédure,
on omet simplement le(s) paramètre(s). Dans la procédure appelée RPG IV, on
peut utiliser la fonction intégrée %PARMS pour déterminer le nombre de paramètres
effectivement passés.

En général, le compilateur utilise un prototype pour vérifier la
longueur d’un paramètre en plus de ses attributs. Toutefois, un prototype peut
indiquer que le paramètre passé risque d’être plus court que la longueur spécifiée.
Valide avec des paramètres de type caractères ou graphique, le mot-clé
OPTIONS(*VARSIZE) permet de passer des paramètres de longueur variable, à 
concurrence de la taille maximale spécifiée dans le prototype. La figure 7a
illustre ce cas de figure.

Au lieu de passer effectivement un paramètre, on peut passer la valeur
spéciale *OMIT au lieu de (ou en plus de) marquer simplement le paramètre
comme optionnel. Le mot-clé OPTIONS(*OMIT) permet de passer la valeur *OMIT y
compris au milieu d’une liste de paramètres. OPTIONS(*OMIT) ne fonctionne
qu’avec des paramètres passés par référence. Dans le programme ou la procédure
appelé, on peut utiliser la fonction intégrée %ADDR pour trouver l’adresse
d’un paramètre ; si l’adresse est *NULL, le paramètre a été omis. 

8. On peut utiliser
les prototypes pour inclure des fonctions C dans les programmes RPG IV.

Les prototypes RPG IV
permettent aux applications de tirer profit de plusieurs fonctions standard IBM,
incluses dans le système d’exploitation sous la forme de fonctions C
classiques. Les fonctions C srand et rand par exemple, classent et génèrent
respectivement un nombre aléatoire. Il se trouve que le RPG ne possède pas de
fonctions équivalentes. Toutefois, en utilisant un prototype adéquat, il est
possible d’invoquer ces fonctions C à  partir de procédures RPG. La figure 8 en
présente un exemple. Le mot-clé EXTPROC dans le prototype identifie la procédure
qui est externe au programme RPG. (Pour de plus amples informations sur la manière
de convertir le prototype d’une API C en PRG IV, consultez l’article "Anatomy
of a Sockets API", NEWS/400, mars 1999).

Il est généralement possible de transposer aisément des définitions C
en prototypes RPG, même lorsque l’on ne maîtrise pas le C. En ce qui concerne
les prototypes de la figure 8, le C définirait le prototype SeedRand de la manière
suivante : 

Void
srand(unsigned int seed)
 

ce qui veut dire que
la fonction srand s’attend à  recevoir un nombre entier non signé comme paramètre,
et ne renvoie aucune valeur (void). Pour sa part, le prototype Rand correspond
à  la définition C suivante : 

Int rand(void) 

ce qui implique que la
fonction rand n’attend aucun paramètre et renvoie un nombre entier. Comme
l’indique le prototype SeedRand de la figure 8, le C impose de passer les paramètres
par valeur. Lors de la compilation d’un module utilisant une fonction C,
assurez-vous de spécifier le répertoire contenant les liens, QC2LE, dans la
commande invoquant le compilateur. 

Autres articles sur le sujet

Cravitz,
Mike. “ Anatomy of a Sockets API ”, NEWS/400, mars 1999.

Meyers,
Bryan. “ Adoptez un style RPG IV ! ”, NEWSMAGAZINE,
septembre 1998.

Meyers,
Bryan. “ Utilisation des directives du compilateur pour réutiliser le
code RPG IV “ , NEWSMAGAZINE, février 1999, p68.

Meyers,
Bryan. “ V3R2 RPG IV — More Function for CISC Systems ”,
NEWS/400, décembre 1996.

Meyers,
Bryan, et Jon Paris. “ Les sous-procédures en RPG IV: réalisez vos
propres “ fonctions intégrées. ” ”, NEWSMAGAZINE, avril
1996.

9. De nombreuses
nouvelles API peuvent être liées, et on peut y accéder en utilisant des
prototypes.

IBM fournit une
multitude de fonctions via des API qui peuvent être intégrées à  des
programmes. Les API peuvent être utilisées pour effectuer des opérations mathématiques
complexes, des fonctions de type date et heure, des services de messagerie, la
gestion mémoire et bien plus. Les fonctions TCP/IP et les interfaces Domino
sont également disponibles à  travers des procédures fournies sous la forme
d’API.

Jusque là , IBM fournissait les API sous la forme de programmes appelés
distincts. Toutefois, plusieurs nouvelles API sont désormais intégrées à  des
programmes de service. Cela permet d’utiliser des techniques ILE pour “ coupler ”
plus solidement les API à  ses propres programmes. Cette méthode permet d’écrire
des prototypes (ou d’inclure des prototypes fournis par IBM dans la bibliothèque
QSYSINC) puis d’inclure l’appel à  une API dans une expression ou d’utiliser
CALLP pour exécuter l’API. 

10. Les procédures
CL peuvent invoquer des procédures RPG (et vice versa). Mais le CL ne supporte
pas le prototypage.

La commande CL CALLPRC
(Call Procedure) permet d’exécuter des procédures qui ont été liées dans le
même programme avec des procédures CL. En fait, il est possible de combiner
des procédures écrites dans n’importe quel langage ILE, et de les lier
ensemble pour construire un programme commun. La commande CALLPRC est très
similaire à  la commande CALL classique, mais elle permet également de définir
une variable CL qui sera utilisée pour accepter une variable renvoyée par une
procédure appelée :

CALLPRC PRC(CALCPMT)                    
+

PARM(&PRINC &INT
&TERM)            +

RTNVAR(&PAYMENT) 

Le CL ne supporte pas le prototypage. Aussi, lorsqu’on développe une
application, il faut s’assurer que les paramètres et l’interface d’appel sont
cohérents.

Téléchargez cette ressource

Guide inmac wstore pour l’équipement IT de l’entreprise

Guide inmac wstore pour l’équipement IT de l’entreprise

Découvrez toutes nos actualités à travers des interviews, avis, conseils d'experts, témoignages clients, ainsi que les dernières tendances et solutions IT autour de nos 4 univers produits : Poste de travail, Affichage et Collaboration, Impression et Infrastructure.

Tech - Par iTPro.fr - Publié le 24 juin 2010