> Tech > Caractères parasites dans le paramètre d’un programme

Caractères parasites dans le paramètre d’un programme

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

Q : Chaque fois qu’il y a un long paramètre dans mon programme, des caractères parasites et incohérents apparaissent après un certain point. Vous pouvez reproduire le problème en exécutant le programme de la figure 1. Pouvez-vous expliquer ce qui ne va pas et comment y

Caractères parasites dans le paramètre d’un programme

remédier ?

R : C’est le fonctionnement même des paramètres sur le System i qui est en cause. Les paramètres de plus de 32 caractères de long présenteront ce problème dès lors qu’une variable ne peut pas être utilisée pour le paramètre. Ce comportement se manifeste dans les cas suivants : utilisation d’un paramètre littéral à partir d’un programme CL, appel d’un programme depuis la ligne de commande avec la commande CALL, soumission d’un programme au batch avec la commande SBMJOB, et appel d’un programme au moyen d’une « API ligne de commande » telle que QCMDEXC, QCAPCMD ou system(). Je vais expliquer pourquoi il en est ainsi, en décrivant le mode de fonctionnement des paramètres.

Les paramètres du System i sont passés par référence, c’est-à-dire que la seule chose passée d’un programme à un autre est une adresse dans la mémoire de l’ordinateur.

Quand un programme fait un appel, il obtient l’adresse de la variable qu’il est en train de passer, la met dans la liste de paramètres, et appelle le programme. Le programme appelé examine la liste de paramètres, voit l’adresse, et établit certaines de ses variables dans la zone de mémoire à laquelle l’adresse fait référence. Comme les variables dans le programme appelant et dans le programme qui est appelé utilisent la même mémoire, elles auront la même valeur.

C’est un mécanisme utile. Il permet au programme appelé de voir les données dans la mémoire de l’appelant, permettant aux données d’être « transmises » au programme. Quand ce programme change les données, celles-ci sont changées dans la mémoire de l’appelant, de sorte que les changements sont également visibles par l’appelant ! Cette technique procure un paramètre bidirectionnel, fort commode. Et aussi très rapide, parce que, quelle que soit la longueur du paramètre, seule une adresse est transmise. Et donc, vous pouvez passer une variable de 32 K aussi rapidement qu’une de 2 octets.

Tout se complique quand des paramètres sont passés sans aucune variable. Ainsi, supposons un programme CL qui appelle un programme RPG et qui utilise un littéral, de la manière suivante :

CALL PGM(MYRPG) PARM(‘Test Message’)

Dans ce cas, il n’y a pas de variable, simplement les mots « Test Message ». Comme le programme s’attend à recevoir une adresse de variable, que devrait-il passer ? Ici, le système en crée une. Il alloue de l’espace en mémoire, y copie la valeur Test Message, et passe l’adresse. Le point délicat est de savoir combien d’espace le système doit allouer. Comme il n’y a pas de variable à passer, comment sait-il combien de mémoire sera nécessaire ?

Des règles spécifiques régissent la quantité de mémoire utilisée. Le système allouera toujours au moins 32 octets d’espace. Si c’est plus long que la valeur (ce serait le cas ici puisque Test Message occupe moins de 32 octets), le système remplit le reste des 32 octets avec des blancs. Quand le littéral dépasse 32 octets, le système alloue exactement la quantité de mémoire nécessaire pour contenir le littéral. Ainsi, dans la commande CALL suivante, le système alloue 36 octets, juste assez pour le littéral et voici ce que le programme reçoit :

CALL PGM(MYRPG) PARM(‘NICE DAY FOR A SWIM IN THE POOL, EH?’)

Si le littéral est un nombre, le processeur de commandes va allouer un champ packé de 15 chiffres de long et 5 décimales, et il passera cela au lieu d’utiliser la règle des 32 octets.

Cela ne concerne pas que les littéraux de programmes CL. Que se passe-t-il quand vous appelez une commande depuis une ligne de commande ou que vous utilisez l’API QCMDEXC, system(), ou QCAPCMD ? Dans de tels cas, toute la chaîne de commande n’est qu’un long champ. Bien que ce champ puisse être une variable, il n’est pas aisé à utiliser parce que chaque paramètre a besoin de sa propre adresse. Donc, le système examine la chaîne de commande, trouve les noms de programmes et les noms de toutes les variables et alloue à nouveau la mémoire selon la règle des 32 octets ou la règle du 15-5 packé.

Même chose pour une commande SBMJOB. Bien que, dans ce cas, vous puissiez avoir des variables pour chaque paramètre, SBMJOB ne peut pas les utiliser parce que la mémoire qui leur est associée ne survivra pas au programme qui a alloué cette mémoire. Le job soumis risque de s’exécuter pendant plus longtemps que le programme qui l’a soumis, il est important qu’il ne fasse pas directement référence aux variables. C’est pourquoi il génère une chaîne de commandes toutes contenues dans un champ, comme celle utilisée à partir de la ligne de commande, et il copie cette chaîne dans le nouveau job. Là encore, cette chaîne doit suivre les règles des 32 caractères ou 15/5.

Revenons en arrière et examinons l’exemple de programme que vous avez soumis (figure 9). Ce programme s’attend à 200 caractères pour son paramètre. Mais, quand vous l’appelez depuis la ligne de commande, de la manière suivante, le système ne réserve que 36 octets de mémoire :

CALL PGM(MSGTEST) PARM(‘This is a test. This is only a test.’)

La ligne de commande a permis à votre programme CL d’accéder à 36 octets, mais le programme CL essaie d’en visualiser 200 ! On devine le problème : il visualisera 164 octets de mémoire au-delà de la quantité que le système a alloué pour le paramètre. Cette mémoire pourrait faire partie d’une autre variable dans un autre programme, ce pourrait être quelque chose qu’utilise le système d’exploitation, ou même de la mémoire non réservée par quoi que ce soit. Et c’est pourquoi apparaissent des caractères parasites, sans aucune signification. En effet, ce que vous voyez est ce qui se trouve dans la mémoire directement après le paramètre. Pour résoudre le problème, vous devez maîtriser la quantité de mémoire allouée à chaque paramètre. Dans votre cas, assurez-vous qu’au moins 200 octets sont mis à la disposition du programme CL qui est appelé. Comment pouvez-vous faire cela ? Trois possibilités viennent aussitôt à l’esprit :

• Déclarer une variable d’au moins 200 caractères dans un programme appelant et s’assurer que votre programme de message n’est appelé que de cette manière. Cette solution sera inopérante si vous devez appeler votre programme au moyen de SBMJOB ou d’une ligne de commande.

• Créer une définition de commande (un objet *CMD) qui précisera la longueur de chaque paramètre. Cela permet au système d’allouer la bonne quantité de mémoire afin que votre programme ne voie jamais rien d’incohérent. Ainsi, votre programme pourra être appelé de la ligne de commande, de CL avec un littéral, ou de SBMJOB.

• Passer un paramètre supplémentaire qui contient la longueur du champ. En fait, c’est ce que fait l’API QCMDEXC elle-même. Elle accepte deux paramètres. Le premier est la chaîne de commandes (qui peut être très grande), et le second est la longueur de cette variable. Vous pouvez ensuite faire en sorte que toute mémoire située au-delà de la quantité qui a été passée soit ignorée.

Pour la plupart des cas, je recommande la deuxième solution. C’est la plus solide et la plus facile. Une simple interface de commande, telle que celle de la figure 10, demandera au système d’allouer la bonne quantité de mémoire. Vous pouvez trouver une autre réponse à votre question dans la section FAQ Midrange.com

Par Scott Klement

Téléchargez gratuitement cette ressource

Le Guide d’Orchestration du Parcours client

Le Guide d’Orchestration du Parcours client

Au-delà de la clarification des nouveaux concepts de gestion du parcours client, ce guide vous permettra de définir, créer et mettre œuvre une orchestration complète articulée autour des trois volets essentiels au succès de l’expérience client et de l’entreprise.

Tech - Par iTPro - Publié le 24 juin 2010