Aller au contenu
ILE · modules · programmes de service · RPG, C, CL

L'ILE sur IBM i, un programme fait de briques

Ce qu'est l'Integrated Language Environment, pourquoi IBM l'a créé, et comment le mettre en place : un programme RPG full free qui appelle une fonction écrite en C et une procédure écrite en CL, lié d'abord en un seul programme, puis à un programme de service. Tout a été compilé, exécuté et débogué sur un IBM i 7.5.

1993annonce de l'ILE, avec la V2R3 d'OS/400
3langages dans un seul programme
4objets : module, programme, programme de service, répertoire
0recompilation du programme pour changer le C

En une phrase

Avec l'ILE, un compilateur ne produit plus un programme mais un module ; on lie ensuite des modules, écrits si l'on veut en RPG, en C, en COBOL ou en CL, pour obtenir un programme ou un programme de service que d'autres programmes partagent.

L'ILE, c'est quoi

L'ILE (Integrated Language Environment) est un ensemble d'outils et de mécanismes du système pour construire des programmes. Seuls les compilateurs ILE en profitent : ILE RPG (le RPG IV), ILE COBOL, ILE C, ILE C++ et ILE CL. Il repose sur quelques objets :

ObjetNomRôle
*MODULEModuleCe que produit un compilateur ILE (CRTRPGMOD, CRTCMOD, CRTCLMOD…). Il contient des procédures, mais ne s'exécute pas seul.
*PGMProgrammeUn ou plusieurs modules liés, dont un porte la procédure d'entrée. Il s'appelle par CALL.
*SRVPGMProgramme de serviceDes modules liés, sans procédure d'entrée : une boîte à outils de procédures, partagée par les programmes qui s'y lient.
*BNDDIRRépertoire de liageUne liste de modules et de programmes de service, où le binder cherche les procédures appelées.
Groupe d'activation(pas un objet)La partie du travail où un programme ILE s'exécute : ses variables, sa mémoire, ses fichiers ouverts.
Des sources aux programmes, en ILE Trois sources, en RPG, en C et en CL, sont compilées chacune en un module. CRTPGM copie les trois modules dans le programme STKCLE. CRTSRVPGM copie les modules C et CL dans le programme de service OUTILS, auquel le programme STKCLE2 est lié par référence. STKCLEsource RPG full free CLECTLsource C CLUSERsource CL (CLLE) *MODULE STKCLECRTRPGMOD *MODULE CLECTLCRTCMOD *MODULE CLUSERCRTCLMOD *PGM STKCLECRTPGM : les 3 modules copiés *SRVPGM OUTILSCRTSRVPGM : C et CL copiés STKCLE2 (CRTBNDRPG) s'y lie par référence
Un compilateur, un module ; le liage assemble les modules.

Pourquoi l'ILE existe

Sur l'AS/400 des débuts, le modèle de programmes est l'OPM (Original Program Model) : on compile un source, on obtient un programme, et un programme en appelle un autre par un appel dynamique, coûteux en ressources. Les applications étaient donc faites de quelques gros programmes, pour limiter les appels. Pour le C et le Pascal, IBM ajoute en V1R2 un modèle étendu, l'EPM. Le 16 février 1993, IBM annonce que la V2R3 d'OS/400 apportera l'ILE.

Ce que l'ILE change, d'après IBM :

  • La liaison. Une procédure appelle une procédure d'un autre module par un appel lié, plus rapide que l'appel dynamique entre programmes. Découper devient rentable.
  • La modularité. On recompile un petit module au lieu d'un gros programme, et la maintenance porte sur des morceaux plus petits.
  • Le mélange des langages. Un même programme peut réunir des modules RPG, COBOL, C, C++ et CL : chacun écrit dans le langage le plus adapté.
  • Des composants réutilisables, rangés dans des programmes de service.
  • La coexistence. Les programmes ILE et OPM s'appellent les uns les autres : on passe à l'ILE progressivement.
  • Un débogueur source commun, qui passe d'un langage à l'autre (démonstration plus bas).
  • Un meilleur contrôle des ressources, grâce aux groupes d'activation.

L'exemple : un programme RPG, un module C, un module CL

Le programme STKCLE liste les articles du fichier ARTICLE (celui de la page Coder en RPG III) avec une clé de contrôle calculée par une fonction C, et affiche l'utilisateur rendu par une procédure CL.

Le module principal, en RPG full free

**FREE
// STKCLE : liste les articles avec leur cle de controle, calculee
// par le module C CLECTL, et l'utilisateur, rendu par le module CL CLUSER.
dcl-f ARTICLE keyed;

// Les procedures des autres modules : un prototype par procedure
dcl-pr cleControle int(10) extproc('cleControle');
  code char(5) const;
end-pr;
dcl-pr utilisateur extproc('CLUSER');
  user char(10);
end-pr;

dcl-s user char(10);
dcl-s cle int(10);

utilisateur(user);
dsply ('Utilisateur : ' + %trim(user));

read ARTICLE;
dow not %eof(ARTICLE);
  cle = cleControle(ARTCOD);
  dsply (ARTCOD + ' cle ' + %char(cle));
  read ARTICLE;
enddo;
*inlr = *on;
dcl-pr cleControle int(10) extproc('cleControle');
Le prototype de la fonction C. Le nom entre apostrophes est le nom exact de la fonction : la casse compte. Sans EXTPROC, RPG chercherait CLECONTROLE, en majuscules, et le liage échouerait.
code char(5) const;
Le code article, passé par référence : la fonction C le reçoit comme un const char *.
dcl-pr utilisateur extproc('CLUSER');
La procédure du module CL porte le nom du module, CLUSER, comme le montre plus bas la liste des procédures exportées. Le prototype RPG peut, lui, s'appeler autrement (utilisateur).
cle = cleControle(ARTCOD);
Un appel de procédure, sans CALL : c'est un appel lié.

Le module C

/* CLECTL : cle de controle d'un code article de 5 caracteres.   */
/* Les chiffres de rang pair comptent double ; la cle complete    */
/* la somme a la dizaine superieure.                              */
#include <ctype.h>

int cleControle(const char *code)
{
    int i;
    int somme = 0;

    for (i = 0; i < 5; i++) {
        if (isdigit((unsigned char) code[i])) {
            int chiffre = code[i] - '0';
            somme += (i % 2 == 0) ? chiffre * 2 : chiffre;
        }
    }
    return (10 - somme % 10) % 10;
}

Une fonction C ordinaire. Sur IBM i, les chiffres sont en EBCDIC (X'F0' à X'F9'), mais ils se suivent comme en ASCII : code[i] - '0' donne bien la valeur du chiffre.

Le module CL

/* CLUSER : rend le nom de l'utilisateur du travail               */
             PGM        PARM(&USER)
             DCL        VAR(&USER) TYPE(*CHAR) LEN(10)

             RTVJOBA    USER(&USER)
             ENDPGM

Le même source qu'un programme CL : PGM, PARM, ENDPGM. Ce qui en fait un module, c'est la commande qui le compile.

Mettre en place 1 : trois modules, un programme

Chaque source se compile en module, avec le compilateur de son langage :

CRTRPGMOD MODULE(JOBIILE/STKCLE) SRCFILE(JOBIILE/QRPGLESRC) DBGVIEW(*SOURCE)Le module RPG (attribut RPGLE)
CRTCMOD MODULE(JOBIILE/CLECTL) SRCFILE(JOBIILE/QCSRC) DBGVIEW(*SOURCE)Le module C (attribut CLE)
CRTCLMOD MODULE(JOBIILE/CLUSER) SRCFILE(JOBIILE/QCLSRC) DBGVIEW(*SOURCE)Le module CL (attribut CLLE)

Puis CRTPGM lie les trois modules en un programme. ENTMOD désigne le module qui porte la procédure d'entrée, celle qui démarre quand on appelle le programme :

CRTPGM PGM(JOBIILE/STKCLE) MODULE(JOBIILE/STKCLE JOBIILE/CLECTL JOBIILE/CLUSER) ENTMOD(JOBIILE/STKCLE)
CALL STKCLE
Écran Entrée de commandes : CALL STKCLE affiche Utilisateur : SAKADM puis A0001 cle 8, A0002 cle 6, A0003 cle 4, A0004 cle 2, A0005 cle 0
Le RPG lit le fichier, le C calcule la clé, le CL rend l'utilisateur : un seul programme.
DSPPGM STKCLE DETAIL(*MODULE) : trois modules, STKCLE attribut RPGLE, CLECTL attribut CLE, CLUSER attribut CLLE
DSPPGM PGM(JOBIILE/STKCLE) DETAIL(*MODULE) : les trois modules et leur langage.

Ici, les modules sont liés par copie : leur code est recopié dans le programme. Le groupe d'activation n'a pas été précisé : avec ACTGRP(*ENTMOD), la valeur par défaut, un module d'entrée RPGLE fait tourner le programme dans le groupe QILE.

Mettre en place 2 : un programme de service

Les procédures C et CL serviront à d'autres programmes : on les range dans un programme de service. Son source de liage dit ce qu'il exporte, dans un ordre qui ne doit plus changer (on ajoute les nouvelles procédures à la fin, pour garder la compatibilité) :

/* OUTILS : les procedures exportees par le programme de service */
             STRPGMEXP  PGMLVL(*CURRENT)
             EXPORT     SYMBOL('cleControle')
             EXPORT     SYMBOL(CLUSER)
             ENDPGMEXP
CRTSRVPGM SRVPGM(JOBIILE/OUTILS) MODULE(JOBIILE/CLECTL JOBIILE/CLUSER) SRCFILE(JOBIILE/QSRVSRC) SRCMBR(OUTILS)
CRTBNDDIR BNDDIR(JOBIILE/OUTILS)
ADDBNDDIRE BNDDIR(JOBIILE/OUTILS) OBJ((JOBIILE/OUTILS *SRVPGM))
DSPSRVPGM OUTILS DETAIL(*PROCEXP) : procédures exportées cleControle et CLUSER
Les deux procédures exportées par OUTILS : cleControle (C, en minuscules) et CLUSER (CL).

Le programme n'a plus besoin de citer les modules : le répertoire de liage suffit. Le même source RPG gagne une ligne de contrôle et se compile en une étape par CRTBNDRPG :

**FREE
// STKCLE2 : le meme programme, lie au programme de service OUTILS
// par le repertoire de liage OUTILS, au lieu de copier les modules.
ctl-opt dftactgrp(*no) actgrp('JOBIILE') bnddir('OUTILS');
dcl-f ARTICLE keyed;
dftactgrp(*no)
Obligatoire : avec DFTACTGRP(*YES), qui sert à la compatibilité OPM, IBM interdit ACTGRP et BNDDIR, et un appel de procédure liée fait échouer la compilation.
actgrp('JOBIILE')
Un groupe d'activation nommé, propre à l'application.
bnddir('OUTILS')
Le répertoire de liage où chercher cleControle et CLUSER.
CRTBNDRPG PGM(JOBIILE/STKCLE2) SRCFILE(JOBIILE/QRPGLESRC) DBGVIEW(*SOURCE)
DSPPGM STKCLE2 DETAIL(*SRVPGM) : programme de service OUTILS de JOBIILE avec sa signature, puis les programmes de service système QRNXIE, QRNXIO, QRNXUTIL et QLEAWI
STKCLE2 est lié par référence à OUTILS, avec sa signature, et aux programmes de service du système dont le RPG a besoin.

Par copie ou par référence : la preuve

Changeons le calcul du module C : les chiffres de rang pair comptent triple au lieu de double.

-            somme += (i % 2 == 0) ? chiffre * 2 : chiffre;
+            somme += (i % 2 == 0) ? chiffre * 3 : chiffre;

On recompile le module, et on remplace seulement le module dans le programme de service, sans toucher aux programmes :

CRTCMOD   MODULE(JOBIILE/CLECTL) SRCFILE(JOBIILE/QCSRC) DBGVIEW(*SOURCE)
UPDSRVPGM SRVPGM(JOBIILE/OUTILS) MODULE(JOBIILE/CLECTL)
CALL STKCLE
CALL STKCLE2
Écran Entrée de commandes : CALL STKCLE donne encore les clés 8 6 4 2 0, CALL STKCLE2 donne les nouvelles clés 7 4 1 8 5
STKCLE garde sa copie de l'ancien module (8, 6, 4, 2, 0) ; STKCLE2 utilise le nouveau OUTILS (7, 4, 1, 8, 5).

STKCLE contient sa propre copie de l'ancien module : il faut le relier pour qu'il change.

UPDPGM PGM(JOBIILE/STKCLE) MODULE(JOBIILE/CLECTL)
Écran Entrée de commandes : UPDPGM STKCLE, programme mis à jour, puis CALL STKCLE donne les clés 7 4 1 8 5
Après UPDPGM, STKCLE donne les mêmes clés que STKCLE2.
CritèrePar copie (CRTPGM MODULE)Par référence (programme de service)
Où est le codeDans chaque programmeUne seule fois, dans le *SRVPGM
Changer une procédureRelier chaque programme (UPDPGM)UPDSRVPGM, une fois pour tous
Objets à livrerLe programmeLe programme et le programme de service
Pour quoiDes modules propres à un programmeDes procédures partagées par plusieurs programmes

Déboguer d'un langage à l'autre

STRDBG suit le programme de module en module, à condition que chacun ait été compilé avec DBGVIEW(*SOURCE). Point d'arrêt sur l'appel de la fonction C, puis F22 (Step into, entrer dans la procédure appelée) :

STRDBG PGM(JOBIILE/STKCLE)
BREAK 22
CALL STKCLE
STRDBG arrêté à la ligne 22 du module STKCLE : cle = cleControle(ARTCOD);
Arrêt dans le module RPG, sur l'appel de la fonction C.
STRDBG dans le module CLECTL : le source C de cleControle, message Etape terminée à la ligne 9
F22 : le débogueur affiche le source C du module CLECTL, dans le même programme.

Dans le module C, les commandes du débogueur suivent la syntaxe du C : EVAL somme affiche la variable, EVAL *code :c 5 les 5 caractères pointés par code.

STRDBG dans le module C, ligne 17 : somme = 2
EVAL somme : 2 pour A0001.
STRDBG dans le module C : *code :c 5 = A0001
EVAL *code :c 5 : A0001.

CLEAR PGM enlève tous les points d'arrêt, F12 laisse le programme finir, et ENDDBG clôt la session.

Mettre l'ILE en place dans une application

  • Sortir du mode compatible. IBM présente CRTBNDRPG avec DFTACTGRP(*YES) comme une stratégie temporaire, pour des applications OPM qu'on ne peut pas convertir d'un coup. Les nouveaux programmes se compilent avec DFTACTGRP(*NO).
  • Regrouper les procédures partagées dans des programmes de service, par domaine (dates, contrôles, accès à un fichier…), avec un source de liage dont on ne change jamais l'ordre.
  • Un répertoire de liage par application, cité dans le CTL-OPT : les programmes n'ont plus à connaître la liste des modules.
  • Un groupe d'activation nommé par application, plutôt que *NEW à chaque appel.
  • Garder les noms exacts : EXTPROC dans la casse de la procédure, surtout pour le C.

Sources

L'exemple a été construit et exécuté sur un IBM i 7.5 (voir la méthode). Les définitions et les règles viennent de ces sources, consultées le 16 octobre 2026 :

  1. IBM i 7.5 Programming : ILE Concepts (SC41-5606-12), IBM (PDF). Définition de l'ILE et ses compilateurs ; les avantages (liaison et appel lié plus rapide, modularité, composants réutilisables, coexistence avec l'OPM, débogueur source) ; OPM puis EPM en V1R2 ; liaison par copie et par référence ; répertoires de liage ; groupes d'activation ; signature et langage de liage.
  2. Integrated Language Environment, Wikipédia (en anglais). Annonce de l'ILE le 16 février 1993, avec la V2R3 d'OS/400.
  3. ILE RPG Reference (SC09-2508-12), IBM, IBM i 7.5 (PDF). EXTPROC : nom externe dans la casse indiquée ; sans EXTPROC, le nom du prototype en majuscules.
  4. ILE RPG Programmer's Guide (SC09-2507-12), IBM, IBM i 7.5 (PDF). CRTBNDRPG crée un module temporaire puis le lie ; DFTACTGRP(*YES) assure la compatibilité OPM et interdit ACTGRP et BNDDIR.
  5. Create Program (CRTPGM), IBM, IBM i 7.5 CL commands. MODULE, ENTMOD, BNDSRVPGM, BNDDIR ; ACTGRP(*ENTMOD) qui donne QILE pour un module d'entrée RPGLE, CBLLE ou CLLE.
  6. Create Service Program (CRTSRVPGM), IBM, IBM i 7.5 CL commands. Création d'un programme de service à partir de modules et d'un source de liage (EXPORT).
  7. Update Service Program (UPDSRVPGM), IBM, IBM i 7.5 CL commands. Remplacer un module dans un programme de service existant.
  8. Create C Module (CRTCMOD), IBM, IBM i 7.5 CL commands. La compilation du module C.
  9. Create Binding Directory (CRTBNDDIR), IBM, IBM i 7.5 CL commands. Le répertoire de liage OUTILS.

Questions fréquentes

Qu'est-ce que l'ILE sur IBM i ?

L'Integrated Language Environment est le modèle de programmes d'IBM i dans lequel un compilateur produit un module (*MODULE), et non un programme. On assemble (on lie) ensuite un ou plusieurs modules, éventuellement écrits dans des langages différents, en un programme (*PGM) ou en un programme de service (*SRVPGM). Les compilateurs ILE sont ceux de RPG, COBOL, C, C++ et CL.

Quelle différence entre un programme et un programme de service ?

Un programme (*PGM) a une procédure d'entrée et s'appelle par CALL. Un programme de service (*SRVPGM) n'a pas de procédure d'entrée : il met des procédures à disposition d'autres programmes, qui s'y lient par référence. Le modifier ne demande pas de recompiler les programmes qui l'utilisent, tant que sa liste d'exportations reste compatible (nouvelles procédures ajoutées à la fin).

Qu'est-ce qu'un répertoire de liage ?

Un objet *BNDDIR qui liste des modules et des programmes de service. On le cite au liage (BNDDIR de CRTPGM, CRTBNDRPG ou de CTL-OPT) au lieu de citer chaque objet : le binder y prend ce qui résout les procédures appelées.

Comment appeler une fonction C depuis du RPG ?

Avec un prototype DCL-PR dont EXTPROC donne le nom exact de la fonction, en respectant la casse : EXTPROC('cleControle'). Sans EXTPROC, RPG cherche le nom du prototype en majuscules. Un paramètre CHAR CONST passé par référence arrive en C comme un const char *.

Faut-il recompiler un programme quand on modifie un module ?

Si le module a été copié dans le programme (CRTPGM MODULE), il faut relier le programme, par exemple avec UPDPGM. S'il est dans un programme de service, on met à jour le programme de service (UPDSRVPGM) et les programmes qui s'y lient prennent la nouvelle version à leur prochaine activation, sans être recompilés, si les exportations n'ont pas changé.