|
L'équipe progG de Ti-Fr
|
Voici les nicks de vos serviteurs ;-)
chickensaver_john
Kevin Kofler
Thibaut
janjan2
TiMad
Iceman89
fréka
Zewoo
Squale92
Verstand
ZdRUbAl
UtOpIaH
et nEUrOne ...
|
|
Une idée ?
|
Une idée pour améliorez cette partie?
ou tout simplement vous souhaitez participer à l'élaborations
des tutos.
Mailez-nous ici
|
| |
Chapitre
XXVI
Nous avons vu au Chapitre
XXIII comment créer et utiliser des librairies dynamiques en C pour
TIGCC. A présent, nous allons voir comment faire pour développer des
librairies statiques sous ce même logiciel...
A titre d'information, sachez que toutes les fonctions de
TIGCC sont implémentées en temps que librairies statiques. Un autre exemple
de librairie statique assez connu est la librairie ExtGraph de la TICT.
Les libraires statiques n'ont pas besoin qu'un fichier particulier
soit installé sur la TI, et elles peuvent être écrites en mode Nostub, ne nécessitant
ainsi pas de Kernel sur la TI...
J'ai écrit ce chapitre dès que j'ai su comment implémenter
des librairies statiques afin de ne pas trop vous influencer : comme vous pourrez
vous en rendre compte, les librairies statiques ont des avantages et des inconvénients,
tout comme les librairies dynamiques... Je vous laisse libre d'utiliser le type
de librairies que vous voulez... mon seul objectif ici est justement de vous
permettre de faire ce choix, en sachant comment développer ces deux types de
fichiers.
Dans ce chapitre, pour des raisons de commodité (aussi bien
pour moi, qui n'aurai pas à trouver de nouvelles fonctions, que pour vous, qui
avez déjà saisi leur fonctionnement), nous ré-utiliserons les fonctions que
nous avons employé au Chapitre
XXIII... Ne soyez donc pas étonné des ressemblances que vous pourrez certainement
remarquer...
I:\
Généralités sur les librairies statiques :
Avant tout, je vais vous demander d'excuser une petite "erreur
de traduction" de ma part... En effet, ce que nous appelons ici librairie
porte, en anglais, le nom de "library" (Et "libraries"
au pluriel). La traduction exacte de ce terme, adaptée à la programmation serait
"Bibliothèque partagée". Mais, par (mauvaise)
habitude, nous n'emploierons jamais le terme de "bibliothèque"
: nous utiliserons, comme nous l'avons déjà fait, celui de "librairie",
qui est plus répandu dans la communauté française des TI-89 et TI-92plus !
Vous pouvez écrie vos librairies statiques soit pour le
mode Kernel, soit pour le mode Nostub, comme vous le souhaitez, selon vos préférences
personnelles, ou ce dont vous avez besoin pour développer vos programmes...
En effet, les librairies statiques ne nécessite pas de Kernel pour une quelconque
relocation, puisque leur code est déjà inclus dans le programme...
- Avantages et utilité des librairies dynamiques
:
- Les librairies statiques permettent en premier lieu de partager des fonctions
utilisées par de nombreux programmes. C'est le rôle que remplissent les
librairies de TIGCC. Elles permettent au programmeur d'utiliser les
fonctions qu'elles comportent, sans se soucier de leur fonctionnement (ou
plutôt, de leur programmation).
- Elles permettent de rajouter des fonctions nouvelles à TIGCC. (C'est
ce que fait la librairie ExtGraph de la TICT).
- Ces librairies n'ont pas forcément besoin de Kernel pour fonctionner,
et ne nécessitent pas la présence de plusieurs fichiers sur la TI, puisque
les instructions utilisées par le programme sont incluses dans celui-ci...
- Inconvénients inhérents à l'utilisation de librairies
dynamiques :
- Utiliser des librairies statiques ne permet pas de réduire l'espace mémoire
occupé par le programme. En effet, les fonctions de la librairie seront
recopiées dans le fichier que vous pourrez envoyer sur votre calculatrice.
- Si plusieurs de vos programmes utilisent la même librairie statique, les
fonctions utilisées seront recopiées dans chaque programme, et seront présentes
plusieurs fois sur la TI (au lieu d'une seule pour le cas des librairies
dynamiques)...
II:\
Création de librairies statiques sous TIGCC :
Pour créer une librairie statique, cela ne se passe pas
exactement de la même façon que pour les librairies dynamiques (sinon, il ne
serait pas utile de l'expliquer !)...
En premier lieu, il va vous falloir créer un fichier .c
pour chaque fonction de la future librairie. (Attention : il ne faut pas regrouper
plusieurs fonctions dans le même fichier .c !)
Notre librairie statique comportera deux fonctions (ben oui,
ce sera une petite librairie :-)). Ces fonctions sont InputStrXY,
et DrawLineFast. Leurs codes sources
sont les même que dans le chapitre traitant des librairies dynamiques...
Il nous faudra donc créer deux fichier comportant l'extension
.c :
A:
Le fichier .c de la première fonction :
Nous allons commencer par la fonction InputStrXY. Pour des
raisons de commodité, nous nommerons donc ce fichier comme ceci : "InputStrXY.c".
A présent, nous pouvons inclure les autres librairies de
TIGCC, ce qui nous permettra d'utiliser d'autres fonctions, à l'interieur
même de celle que nous sommes actuellement en train d'écrire... Pour cela, nous
agirons exactement de la même façon que depuis le premier chapitre de ce tutorial,
c'est-à-dire que nous utiliserons cette commande :
#include <tigcclib.h>
Il ne nous reste plus qu'à écrire le code de notre fonction...
Le voici :
void InputStrXY(short
x, short y,
char *buffer,
short maxlen)
{
/* Liste des Arguments :
x : coordonnées en X du point où la demande apparaîtra à l'écran.
y : coordonnées en Y du point où la demande apparaîtra à l'écran.
buffer : la chaîne de caractères où le résultat sera stocké.
maxlen : le nombre maximal de caractères qu'il sera possible d'entrer.
*/
SCR_STATE ss;
short key,
captured, i=0;
void CaptureHandler (EVENT
*ev)
{
if (ev->Type
== CM_STRING)
captured = *(ev->extra.pasteText);
}
MoveTo(x, y);
buffer[0]
= 0;
SaveScrState (&ss);
do
{
printf_xy(ss.CurX,
ss.CurY, "%s_
", buffer);
// Note that
two spaces are required if F_4x6 font is used
key = ngetchx();
if (key
== KEY_CHAR && i
< maxlen)
{
EVENT ev;
ev.Type =
CM_KEYPRESS;
ev.extra.Key.Code
= key;
EV_captureEvents (CaptureHandler);
EV_defaultHandler (&ev);
EV_captureEvents (NULL);
buffer[i++]
= captured;
}
if (key
>= ' ' &&
key <= '~' &&
i < maxlen) buffer[i++]
= key;
if (key
== KEY_BACKSPACE &&
i) i--;
buffer[i]
= 0;
}while (key
!= KEY_ENTER);
}
Nous avons ainsi terminé l'écriture de la première fonction
de notre future librairie statique.
B:
Le fichier .c de la seconde fonction :
Nous pouvons donc à présent nous intéresser au fichier .c
qui correspondra à la seconde fonction de notre librairie. Il s'agit de la fonction
DrawLineFast, que nous avons déjà employé
lorsque nous avons écrit notre librairie dynamique, il y a de cela trois chapitres...
Nous allons procéder exactement de la même façon que pour
la fonction InputStrXY, en introduisant
tout d'abord la commande d'inclusion des autres librairies, puis le code de
notre fonction.
Nous travaillerons ici avec un autre fichier .c, que
nous aurons pris soin de nommer "DrawLineFast.c". Voici le code de
ce fichier :
#include <tigcclib.h>
void DrawLineFast(short
x1, short y1,
short x2, short
y2, short mode)
{
/* Liste des Arguments :
x1 : coordonnées en X du point de départ.
y1 : coordonnées en Y du point de départ.
x2 : coordonnées en X du point d'arrivée.
y2 : coordonnées en Y du point d'arrivée.
mode : Le mode selon lequel la ligne sera tracée. mode peut prendre pour valeurs
: A_NORMAL, A_REVERSE, A_XOR.
*/
short x =
x1, y = y1;
short dx =
abs (x2 - x1),
dy = abs (y2
- y1);
short ystep =
(y1 < y2) ? 1
: -1,
pystep = 30 *
ystep;
short mov =
dx ? 0 :
-1;
unsigned char *ptr
= (char*)(void
*)LCD_MEM + 30
* y + (x >>
3);
short mask =
1 << (~x
& 7);
if (x1
< x2)
while (x
!= x2 || y !=
y2)
{
if(mode
== A_NORMAL)
*ptr |=
mask;
if(mode
== A_REVERSE)
*ptr &=
mask;
if(mode
== A_XOR)
*ptr ^=
mask;
if
(mov < 0)
y += ystep, ptr
+= pystep, mov +=
dx;
else
{
mov
-= dy;
if
(++x & 7)
mask >>= 1;
else
ptr++, mask =
0x80;
}
}
else
while (x !=
x2 || y != y2)
{
if(mode
== A_NORMAL)
*ptr |=
mask;
if(mode
== A_REVERSE)
*ptr &=
mask;
if(mode
== A_XOR)
*ptr ^=
mask;
if
(mov < 0)
y += ystep, ptr
+= pystep, mov +=
dx;
else
{
mov
-= dy;
if
(x-- & 7)
mask <<= 1;
else
ptr--, mask =
1;
}
}
}
Et voilà, la seconde fonction de notre future librairie
est écrite...
C:
Création de la librairie statique en elle-même :
Pour l'instant, nous avons créé les codes sources correspondant
aux différentes fonctions de notre librairie... Il nous faut à présent les compiler,
afin de véritablement créer celle-ci... Malheureusement, il ne s'agit pas ici
d'une compilation tout à fait normale... En effet, nous ne voulons pas obtenir
un fichier pour calculatrice (comportant l'extension .9xz ou .89),
mais un fichier d'archive, comportant l'extension .a.
Si j'ai bien compris, l'IDE de TIGCC devrait nous
permettre de compiler ces fichiers pour obtenir notre librairie (Option/projet)...
Mais, à chaque fois que j'ai essayé, j'ai obtenu un message d'erreur de la part
de TIGCC... J'ai donc laissé tomber l'IDE, et j'ai donc du employer l'autre
méthode (une fois n'est pas coutume, n'est-ce pas ?).
Pour ceux d'entre vous qui ont déjà eu la chance de pas
mal travailler sous MS-DOS avant de passer à Windows (ça a un peu été
mon cas, mais j'étais tout petit, et je ne m'en souviens donc plus trop... dommage,
car c'est encore parfois bien utile :-)), je penses que ça va vous rappeler
quelques bons souvenirs... Pour ceux qui ne connaissent pas du tout MS-DOS,
vous n'allez pas comprendre grand chose (et, malheureusement, je ne vais pas
vous fournir énormément d'explications : ce n'est pas le but de ce tutorial...).
Pour compiler les différents fichiers sources que nous avons
écrit, et les regrouper dans une seule librairie statique, nous allons devoir
créer un fichier comportant l'extension .bat, et contenant toutes les
commandes MS-DOS qui nous permettront d'arriver à nos fins...
Voici le code de ce fichier, que vous pourrez, par exemple,
nommer "Stalibbuild.bat", ou quelque chose d'approchant... (vous pouvez
le créer à partir du bloc-note de MS-Windows, et, ensuite, changer l'extension...)
:
ECHO OFF
CLS
ECHO Creation de la librairie statique du Chapitre XXVII du tuto C de la TCI...
SET chemin_vers_AR=C:\Progra~1\TIGCC\Bin\ar
ECHO Compilation des fichier sources .c en fichiers objets .o
tigcc -O3 -fomit-frame-pointer InputStrXY.c -Wall -W -c
tigcc -O3 -fomit-frame-pointer DrawLineFast.c -Wall -W -c
ECHO Regroupement des fichiers objets .o en un fichier archive .a
%chemin_vers_AR% -r statlib1.a InputStrXY.o
%chemin_vers_AR% -r statlib1.a DrawLineFast.o
ECHO Effacement des fichiers objets .o
DEL *.o
SET chemin_vers_AR=
ECHO Creation de la librairie statique : TERMINEE !!!
Bon, allez, je suis de bonne humeur (lol), alors
je vais quand même expliquer deux ou trois petit trucs :
- ECHO : Cette instruction
affiche à l'écran la phrase qui est à sa suite. Si cette "phrase"
est OFF, seul les commentaires seront
affichés : les commandes ne le seront plus...
- CLS : Cette instruction
efface le contenu de l'écran (ou de la fenêtre MS-DOS).
- SET : Cette instruction
permet d'associer une valeur à une variable (pour simplifier).
- DEL : Cette instruction provoque
l'effacement des fichiers qui sont placé en "argument"... (Ici,
*.o signifie que tous les fichier
du répertoire comportant l'extension .o seront effacés).
- Les deux lignes commençant par tigcc
permettent de compiler les sources en .c, afin d'obtenir les fichiers
objet .o correspondant.
- Les deux lignes commençant par %chemin_vers_AR%
permettent de grouper les fichiers objet en un seul fichier, notre librairie.
- Une petite remarque au passage : étant donné que nous travaillons ici sous
DOS, ce sont les noms DOS qu'il faut utiliser pour les répertoires... Ainsi,
"Program Files", le répertoire
d'installation par défaut de TIGCC est noté "progra~1"...
- Aure chose : le programme que nous utilisons pour lier tous les fichiers
objets en une seule librairie est le programme AR.exe, situé dans le
répertoire bin de TIGCC... C'est le chemin d'accès de ce fichier
que nous avons affecté à la variable chemin_vers_AR...
Maintenant que votre fichier .bat est prêt, il
ne vous reste plus qu'à double-cliquer dessus, pour le lancer. Si vous n'avez
pas commis d'erreur, il s'exécutera correctement, et vous verrez apparaître
dans le répertoire où il se situe (ainsi que les sources !), un fichier comportant
l'extension .a, et dont le nom sera celui que vous aurez utilisé dans
le fichier .bat.
Ca y est, nous avons enfin obtenu notre librairie statique
!!! Il ne nous reste plus à présent qu'à l'utiliser...
III:\ Le
fichier Header qui permettra d'utiliser la librairie :
De la même façon que pour toutes les librairies de TIGCC
(qui sont implémentées comme des librairies statiques), il faut créer un fichier
Header (comportant l'extension .h) qui servira à "déclarer" les différentes
fonctions que nous venons d'écrire, afin de permettre leur utilisation. Celui-ci
devra par la suite être inclus dans le fichier comportant le code source du
programme utilisant la librairie. (Nous verrons comment faire dans la suite
de ce chapitre).
Ce que je vous conseille de faire est, pour des raisons
de facilités de navigation, de placer directement de fichier header dans votre
projet TIGCC en cours (celui que vous utiliserez pour le programme.).
Il vous est aussi possible d'enregistrer ce fichier header
dans le répertoire Include\C de TIGCC...
Nous verrons dans la partie suivante de ce Chapitre comment
faire pour l'utiliser dans ces deux cas, mais sachez que je préfère la première
solution, car elle permet de regarder le code du header de temps en temps pendant
l'écriture du programme.
A:
Les bases communes à tous les Headers :
De la même façon que pour les librairies dynamiques, il
convient de "déclarer" l'utilisation de la librairie. En supposant
que notre librairie est nommée "statlib1.a", il nous faudra placer
ces lignes de code au début de notre fichier Header (que nous nommerons "statlib1.h")
:
#if !defined(__statlib1__)
#define __statlib1__
Et, à la fin du fichier Header, il conviendra de placer
cette commande :
#endif
B:
Le "code" du Header :
Entre des deux séries de commandes destinées au pré- processeur,
il va nous falloir placer les définitions (les prototypes) des fonctions incluses
dans la librairie. Voici ce que nous devrons écrire pour notre librairie :
extern void InputStrXY(short
, short , char
*, short);
extern void
DrawLineFast(short ,
short , short ,
short , short);
Attention : il
ne faut pas oublier de déclarer ces fonctions comme étant extern
(de la même façon que pour les librairies dynamiques...).
IV:\
Le code du programme utilisant la librairie :
A:
Utilisation du fichier Header :
Nous avons dit précédemment qu'il était possible d'enregistrer
le fichier Header de deux manières différentes :
- Dans le répertoire TIGCC\Include\C
=> Vous devrez mettre au début de votre programme, ceci :
#include <statlib1.h>
C'est ce que vous faites pour toutes les libraires de TIGCC
(même si elles ne fonctionnent pas selon le même principe !).
- Dans le répertoire où est enregistré votre projet (dans les cas où, par
exemple, c'est une librairie que vous ne comptez utiliser que pour un seul
programme). => Vous devrez mettre ceci au début de votre programme :
#include "statlib1.h"
B:
Avant d'utiliser les fonctions de la librarie :
Avant d'utiliser les fonctions de la librairie que nous
avons créé, il y a encore une chose à faire : il faut inclure celle-ci à notre
projet... Pour cela, cliquez sur l'icône correspondant à la fonction "Add
files" de TIGCC (C'est la première possibilité du menu "Project").
Ensuite, naviguez sur votre Disque jusqu'à trouver le fichier correspondant
à votre librairie (ici, le fichier "statlib1.a"), et double-cliquez
dessus...
C:
Utilisation des fonctions de la librairie :
A présent, nous pouvons enfin utiliser les fonctions de
la librairie statique que nous avons écrit... (enfin :-))
Pour cela, il suffit d'agir EXACTEMENT de la même façon
que pour toutes les fonctions intégrées aux librairies de TIGCC. En effet,
le fichier Header que nous avons créé précédemment correspond au type de headers
utilisés par TIGCC pour ses librairies internes, qui sont elles- mêmes
crées de la même façon que notre librairie statique.
Nous pourrons donc, par exemple, effecteur le manipulation
suivante pour entrer une chaîne de caractères dans la variable correspondante
de la librairie :
InputStrXY(20, 20, buffer_STR, 14);
Et, naturellement, il est aussi possible d'afficher
le contenu de celle-ci, en utilisant des instructions "normales" de
TIGCC :
DrawStrXY(20, 20, buffer_STR, A_NORMAL);
Pour utiliser la fonction de dessin rapide de lignes,
il conviendra de faire quelque chose ressemblant à ceci :
DrawLineFast(10, 20, 50, 75, A_NORMAL);
Et voici le code source du programme qui va ici nous servir
d'exemple :
#define OPTIMIZE_ROM_CALLS
#define SAVE_SCREEN
#include <tigcclib.h>
#include "statlib1.h"
short _ti92plus,
_ti89;
void _main(void)
{
short
i=0;
short lcd_width =
LCD_WIDTH;
short lcd_height =
LCD_HEIGHT;
char buffer_STR[15];
ClrScr();
FontSetSys(F_6x8);
DrawStrXY(10,
10, "Votre
nom ?", A_NORMAL);
InputStrXY(20,
20, buffer_STR,
14);
for(i=0
;
i<lcd_height
;
i++)
{
DrawLineFast(0,
0,
lcd_width-1,
lcd_height-i,
A_NORMAL);
DrawLineFast(lcd_width-1,
0,
0,
lcd_height-i,
A_NORMAL);
DrawLineFast(0,
lcd_height,
lcd_width-1,
i,
A_NORMAL);
DrawLineFast(lcd_width-1,
lcd_height,
0,
i,
A_NORMAL);
}
ClrScr();
for(i=0
;
i<lcd_height
;
i++)
{
DrawLineFast(0,
0,
lcd_width-1,
lcd_height-i,
A_XOR);
DrawLineFast(lcd_width-1,
0,
0,
lcd_height-i,
A_XOR);
DrawLineFast(0,
lcd_height,
lcd_width-1,
i,
A_XOR);
DrawLineFast(lcd_width-1,
lcd_height,
0,
i,
A_XOR);
}
for(i=0
;
i<lcd_height
;
i++)
{
DrawLineFast(0,
0,
lcd_width-1,
lcd_height-i,
A_REVERSE);
DrawLineFast(lcd_width-1,
0,
0,
lcd_height-i,
A_REVERSE);
DrawLineFast(0,
lcd_height,
lcd_width-1,
i,
A_REVERSE);
DrawLineFast(lcd_width-1,
lcd_height,
0,
i,
A_REVERSE);
}
ClrScr();
DrawStrXY(10,
10, "Au
revoir", A_NORMAL);
DrawStrXY(70,
10, buffer_STR,
A_NORMAL);
ngetchx();
}
Le code de ce programme étant des plus banals, mis à part
le fait qu'il fait appel à des fonctions non incluses d'origine dans TIGCC,
je ne le commenterai pas... Tous son contenu a déjà été étudié précédemment
dans ce tutorial. Si jamais vous ne vous souvenez pas de quelques chose, je
vous encourage fortement à revenir un peu en arrière, ça ne fait jamais de mal...
A présent, à partir des connaissances que vous avez acquis
à travers ce Chapitre, vous devriez sans problème être capable de développer
vos propres librairies statiques pour TIGCC... Bon courage.
Retour
au menu général
Chapitre
XXVII
|
|