Home   Archives    Hardware   Programmation   Challenges   Forum   Le Mag    Faq   La Communauté   L'Equipe
 
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

Les raccourcis
 

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


 


Copyright © Ti-Fr v2.0 1999-2002