ILE RPG-IV : manipulations de pointeurs en V3R10

BoTTom |    Changer de couleur
              RPG IV permet de manipuler des pointeurs 
 
 1/ pointeur d'adresse, pointe sur un espace mémoire(variable ou *USRSPC)
 
 Les pointeurs d'adresse peuvent être utilisés avec les APIs de gestion
  dynamique de mémoire (le "tas", heap en anglais).
 
 2/ pointeur de procédure, pointe sur une procédure liée dans le même pgm.
 
 Définition d'un pointeur : 
 
  variable de 16 octets (sur AS) contennant une adresse virtuelle.
   (la notion de tableau de pointeurs est admise)
 
 Déclaration en RPG: 
 
 Spécif D:
                                       !-- type de variable "*" = pointeur.
 Pointeur d'adresse.                   v
     DSPACE            S               * [DIM(xxx) = tableau de pointeurs]
 Pointeur de procédure.
     DPROC             S               *   PROCPTR


|    Changer de couleur
 
 Un pointeur contient par défaut la valeur *NULL, il ne pointe sur rien.
 
 il peut se voir assigner une valeur de deux manières:
 
 Copie du contenu d'un pointeur dans un autre
     C                   eval      ptr1 = ptr2
 
 Résolution d'une adresse
 
 Adresse d'une structure (variable, DS, tableau, etc..)
   pour un pointeur d'adresse.
     C                   eval      ptr1 = %ADDR(variable)
 Adresse d'une procédure liée(en respectant la notation minuscule/MAJUSCULE)
   pour un pointeur de procédure.
     C                   eval      pptr = %PADDR('nom-procédure')
 
 La résolution peut être faite lors de l'initialisation du pgm par :
 
     DSPACE            S               *   INZ(%ADDR(variable))
 
     DPROC             S               *   PROCPTR INZ(%PADDR('nom-proc'))


|    Changer de couleur
 
  Et enfin, des APIs systèmes renvoient maintenant des pointeurs :
 
     QUSPTRUS, retourne le pointeur de début d'un User Space
                (manipulation plus rapide)
 
     CEEGTST, API liable, alloue dynamiquement de la mémoire et retourne
               l'adresse de début sous forme de pointeur.
                  (voir plus loin dans ce cours)
 Manipulation: 
 
 Les pointeurs s'utilisent de la manière suivante:
 
  1/ on va définir une structure (en général DS), basée sur un pointeur.
 
     Dptr              S               *
 
     Ddata             DS                  based(ptr)
     D  zone1                         5
     D  zone2                        10
     D  zone3                         7  2
 


|    Changer de couleur
 
 Il s'agit d'une structure "théorique", qui n'a pas d'existence propre,
  et qui viendra découper la zone mémoire référencée par le pointeur,
  quand ce dernier aura une valeur valide.
 
 l'instruction    Z-ADD    0          ZONE3
 
   provoque une erreur MCHxxxx, si ptr n'a pas été renseigné.
 
 Quelques exemples:
 
     Dstructur         DS
     D  zona                          5
     D  zonb                         10
     D  zonc                         12
     Dptr              S               *
     Dsolo             S             10    based(ptr)
     C                   eval      ptr = %ADDR(zonb)
     C* test vrai :
     C                   if        solo = zonb
     C* également vrai :
     C                   if        %addr(solo) = %addr(zonb)


|    Changer de couleur
 
     Dtbl              S              5    DIM(30)
 
     Dtbptr            S               *   DIM(30)
 
     C                   eval      tbptr(1) = %ADDR(tbl)
      * tbptr(1) contient l'adresse de tbl, élément n°1 (début de tableau)
     C                   eval      tbptr = %ADDR(tbl)
      * tous les éléments de tbptr contiennent l'adresse de tbl, élément 1
     C                   eval      tbptr = %ADDR(tbl(*))
      * chaque élément de tbptr contient l'adresse de l'élément de
         même rang dans tbl [tbptr(1) = adresse de tbl(1),
                             tbptr(2) = adresse de tbl(2), etc...]
 Utilisation : 
 
 V3R10 
 Pour ce déplacer dans une structure il faut redéfinir la variable dans
  laquelle on veut se déplacer, sous forme de tableau de x fois 1 c.
 
 V3R70 
 
 Ceci a été corrigé en V3R7, qui accepte prt = ptr + x .


|    Changer de couleur
 
     Dfiller           DS
     D espace                     32767
     Dptr              S               *
     Ddata             DS                  based(ptr)
     D  zone1                         5
     D  zone2                        10                ################# 
     D  zone3                         5S 2             #               # 
      * initialisation au début de la structure        #  EXEMPLE :    # 
 --> C                   eval      ptr = %addr(espace) #               # 
     C                   eval      x = 1               # (suivez --> ) # 
      * décalage d'une longueur                        ################# 
     C                   eval      ptr = ptr + %size(data)
Soit espace (adresse=12601) :
              1         2         3         4         4
12600....+....0....+....0....+....0....+....0....+....9
+ 50 CODE1code n° un12345CODE2code n° 2 67890CODE3code
+100 n° 3 54321CODE5code n° 5 98765CODE6code n° 6 43210
+150   etc ... etc ...
 
  ptr = *NULL  ! x =       ! data = '                    '
 


|    Changer de couleur
 
     Dfiller           DS
     D espace                     32767
     Dptr              S               *
     Ddata             DS                  based(ptr)
     D  zone1                         5
     D  zone2                        10                ################# 
     D  zone3                         5S 2             #               # 
      * initialisation au début de la structure        # Modifier ptr  # 
 --> C                   eval      ptr = %addr(espace) #      =        # 
     C                   eval      x = 1               # modifier DATA # 
      * décalage d'une longueur                        ################# 
     C                   eval      ptr = ptr+ %size(data)
Soit espace (adresse=12601) :
              1         2         3         4         4
12600....+....0....+....0....+....0....+....0....+....9
+ 50 CODE1code n° un12345 ODE2code n° 2 67890CODE3code
+100 n° 3 54321CODE5code n° 5 98765CODE6code n° 6 43210
+150   etc ... etc ...
 
  ptr = 12601  ! x =       ! data = 'CODE1code n° un12345'
 


|    Changer de couleur
 
     Dfiller           DS
     D espace                     32767
     Dptr              S               *
     Ddata             DS                  based(ptr)
     D  zone1                         5
     D  zone2                        10                ################# 
     D  zone3                         5S 2             #               # 
      * initialisation au début de la structure        #  x = 1        #  
 ### C                   eval      ptr = %addr(espace) #               # 
 --> C                   eval      x = 1               #               # 
      * décalage d'une longueur                        ################# 
     C                   eval      ptr = ptr+ %size(data)
 
              1         2         3         4         4
12600....+....0....+....0....+....0....+....0....+....9
+ 50 CODE1code n° un12345 ODE2code n° 2 67890CODE3code
+100 n° 3 54321CODE5code n° 5 98765CODE6code n° 6 43210
+150   etc ... etc ...
 
  ptr = 12601  ! x =    1  ! data = 'CODE1code n° un12345'
 


|    Changer de couleur
 
     Dfiller           DS
     D espace                     32767
     Dptr              S               *
     Ddata             DS                  based(ptr)
     D  zone1                         5
     D  zone2                        10                ################# 
     D  zone3                         5S 2             #               # 
      * initialisation au début de la structure        #  %size(data)  #  
 ### C                   eval      ptr = %addr(espace) #   = 20, donc  # 
     C                   eval      x = 1               #  ptr = 12621  # 
      * décalage d'une longueur                        ################# 
 --> C                   eval      ptr = ptr+ %size(data)
 
              1         2         3         4         4
12600....+....0....+....0....+....0....+....0....+....9
+ 50 CODE1code n° un1234 CODE2code n° 2 67890 ODE3code
+100 n° 3 54321CODE5code n° 5 98765CODE6code n° 6 43210
+150   etc ... etc ...
 
  ptr = 12621  ! x =   21  ! data = 'CODE2code n° 2 67890'
 


|    Changer de couleur
 
     Dfiller           DS
     D espace                     32767
     Dptr              S               *
     Ddata             DS                  based(ptr)
     D  zone1                         5
     D  zone2                        10                 ################# 
     D  zone3                         5S 2              #  si cet       # 
      * initialisation au début de la structure         #  ordre est    #  
 ### C                   eval      ptr = %addr(espace)  #  dans une     # 
     C                   eval      x = 1                #  boucle, on   # 
     C                   DOU       ...                  #  va "pointer" #   
 --> C                   eval      ptr=ptr+%size(data)  #  tous les     # 
                                                        #  éléments de  #  
              1         2         3         4           #  "espace"     # 
12600....+....0....+....0....+....0....+....0....+....9 ################# 
+ 50 CODE1code n° un12345CODE2code n° 2 6789 CODE3code  
+100 n° 3 54321 ODE5code n° 5 98765CODE6code n° 6 43210
+150   etc ... etc ...
 
  ptr = 12641  ! x =   41  ! data = 'CODE3code n° 3 54321'
 


|    Changer de couleur
 C'est la technique qu'il faudra utiliser avec les User Space.
 
 
 Avec l'APi d'allocation dynamique de mémoire il faudra utiliser
  les listes chainées:
 
     Dtas_id           S              9B 0 INZ(0)
     Ddta_size         S              9B 0 INZ(%size(data))
      * l'API CEEGTST doit faire référence à un tas créé au préalable
      * (par API CEECRHP, qui renvoie un identifiant binaire) ou utiliser
      * le tas par défaut que chaque groupe d'activation possède.
      *
      * Il faut alors initialiser l'indentifiant à zéro binaire.
     Dwptr             S               *
     Dptr              S               *
     Ddata             DS                  based(ptr)
     D  preced                         *
     D  zone1                         5
     D  zone2                        10
     D  zone3                         5S 2
     D  suivant                        *
      * intialisation du premier poste


|    Changer de couleur
     C                   callb     'CEEGTST'
     C                   parm                    tas_id
     C                   parm                    dta_size
     C                   parm                    ptr
     C                   eval      preced = *NULL      (pas de précédent)
      *
     C                   DOU       ( test logique)
     C* traitement de ce poste
     C*  et allocation du suivant
     C                   if        (même test logique)
     C                   callb     'CEEGTST'
     C                   parm                    tas_id
     C                   parm                    dta_size
     C                   parm                    suivant (addr du suivant)
     C                   eval      wptr = ptr
     C                   eval      ptr = suivant
     C                   eval      preced = wptr         (addr du précédent)
     C* ou fin de liste
     C                   else
     C                   eval      suivant = *NULL       (pas de suivant)
     C                   endif




©AF400