Etape 4 : écriture du fichier qtis1.cpp

Ce fichier va contenir le code source des deux fonctions de notre librairie, à savoir une fonction qui calcule les jours Julien et une fonction de conversion des angles. C'est bien sur le centre de votre librairie. Voici le texte complet, qui va constituer le fichier
qtis1.cpp (comme toujours le nom des fichiers source est arbitraire - ici l'abréviation signifie Quick Traitement Image (fonctions de) Service) :

// Projet      : AudeLA
// Librairie   : LIBQM
// Fichier     : QTIS1.CPP
// Description : Fonctions utilitaires
// ===================================

#define XTERN
#include "libqm.h"

// ***************** dms2deg *******************
// dms2deg
// Convertie un angle en degrés/minutes/secondes
// en degrés décimaux
// *********************************************

int dms2deg(int d,int m,double s,double *angle)
{
*angle=((s/60.0+(double)m)/60)+(double)d;
return OK;
}

// ******************* jd *********************
// Retourne le jour Julien correspondant à une date        
// annee : valeur de l'annee correspondante                
// mois  : valeur du mois correspondant                    
// jour  : valeur du jour decimal correspondant            
// *jj   : valeur du jour Julien converti           
// ********************************************

int jd(int annee,int mois,double jour,double *jj)
{
double a,m,j,aa,bb;

a=(double)annee;
m=(double)mois;
j=jour;
   
if (m<=2)
   {
   a=a-1;
   m=m+12;
   }

aa=floor(a/100);
bb=2-aa+floor(aa/4);
*jj=floor(365.25*(a+4716))+floor(30.6001*(m+1))+j+bb-1524.5;
return OK;
}

Notez que les commentaires sont de couleur verte.

Les premières lignes définissent une constante et charge le fichier de définition qm.h au moment de la compilation (celui-ci sera décrit plus loin) :

#define XTERN
#include "libqm.h"

On trouve ensuite le corps de la fonction dms2deg qui effectue la conversion des degrés sexagécimaux en degrés décimaux, puis le corps de la fonction jd qui calcule le jour Julien à partir d'une date du calendrier en jour-mois-année. Ces fonctions sont simples et pour qui connaît le langage C, n'attirent pas de commentaires particuliers.

Pour écrire le fichier qtis1.cpp, rien de plus simple : activez la commande New... du menu File. Dans la boite de dialogue qui s'ouvre, sélectionnez le type de fichier C++ Source File et entrez le nom du fichier qtis1 (pensez à cocher la case Add to project).

Validez en cliquant sur OK, puis entrez le code dans l'éditeur. Le résultat doit ressembler à ceci :

 

Sauvegardez votre travail en faisant Save all depuis le menu File (on ne sait jamais !).

Pour compléter le travail il faut éditer le fichier de déclaration libqm.h dont le source est ci-après. Ce fichier déclare de nombreuses constantes et fonctions. Toutes ne sont pas indispensables pour l'instant mais autant entreprendre l'écriture complète de libqm.h dès à présent, c'est autant de temps gagner pour la suite.

// Projet      : AudeLA
// Librairie   : LIBQM
// Fichier     : LIBQM.H
// Description : Déclaration des fonctions expotés
// ===============================================

#include <string.h>
#include <stdio.h>
#include <io.h>
#include <math.h>
#include <windows.h>

#include "tcl.h"
#include "tk.h"

#define OK  0
#define PB  1

#pragma pack (1)

#ifndef XTERN
#   define XTERN extern
#endif

//--- Ajouter ici la déclaration des variables globales ---
XTERN int g_nb_alloc,g_nb_free;

typedef struct
   {
   float *p;
   short imax;
   short jmax;
   short sh;
   short sb;
   } IMAGE;

//--- Fonction d'initialisation de la librairie ---
extern "C" int __stdcall Qm_Init(Tcl_Interp *interp);

//--- Ajouter ici la déclaration des fonctions d'appel des commandes ---
int CmdDms2deg(ClientData clientData,Tcl_Interp *interp,
               int argc,char *argv[]);
int CmdJd(ClientData clientData,Tcl_Interp *interp,
          int argc,char *argv[]);
int CmdOffset(ClientData clientData,Tcl_Interp *interp,
              int argc,char *argv[]);
int CmdWindow(ClientData clientData,Tcl_Interp *interp,
              int argc,char *argv[]);

//--- Ajouter ici la déclaration des fonctions internes ---
int get_image_info(IMAGE **image,int buffer,Tcl_Interp *interp);
int dms2deg(int d,int m,double s,double *angle);
int jd(int annee,int jour,double heure,double *jj);
int offset(short cst,short imax,short jmax,float *p);
short calc_window(short x1,short y1,short x2,short y2,
                  short imax,short jmax,short imax2,
                  short jmax2,
                  float *p,float *p_out);
void *_malloc(size_t longueur);
void _free(void *block);

Pour éditer le fichier libqm.h appelez à nouveau la boite de dialogue New, mais cette fois en sélectionnant le type de fichier C/C++ Header File et en fournissant le nom libqm. Entrez ensuite le code ci-dessus.

Notez que libqm.h charge lui-même les fichiers tcl.h et tk.h qui contiennent l'ensemble des déclarations de la librairie Tcl et de son extension Tk. Ces deux fichiers sont fournies avec toutes les distributions de Tcl/Tk, cependant il est recommandé ici d'utiliser une version très légèrement modifiée, adaptée à l'écriture de notre librairie. Vous pouvez télécharger ces deux fichiers en cliquant ici (fichier include.zip de 25Ko à décompresser dans le répertoire où se trouve vos sources, dans notre exemple c:\qm\libqm\).

D'autres fichiers de définition sont nécessaires pour une compilation sans erreur de votre code source. Vous devez :

  1. Créer un nouveau répertoire ayant pour nom "X11" à partir du répertoire où se trouve votre code source.
  2. Télécharger des définitions propre à Tcl en cliquant ici (fichier x11.zip de 32 Ko).
  3. Décomprimer ce fichier dans le répertoire x11 que vous avez créer (dans notre exemple le chemin de ce répertoire sera donc c:\qm\libqm\x11).

A ce stade vous pouvez compiler qtis1.cpp afin de détecter d'éventuelles erreurs de frappe. Mais avant cela il est important de configurer certaines options du compilateur et de l'éditeur de lien. A partir du menu Project lancez la commande Settings... Dans la boite de dialogue qui s'ouvre choisissez l'onglet General puis une compilation de type Win32 Release (à la rubrique Setting For:). L'autre option possible est une version de débogage qui ne devrait pas être utile ici (une version Release, c'est-à-dire de diffusion, de votre librairie est bien plus compacte qu'une version servant au debogage).

Activez ensuite l'onglet Link et dans la zone de texte Output file name donnez le chemin définissant le répertoire où vous souhaitez voir sauvegarder automatiquement votre librairie après sa construction. Dans notre exemple nous choisissons de mettre automatiquement la DLL dans le répertoire audela\binwin\ qui est le lieu approprié lorsque l'on travaille sous Audela (il serait néanmoins possible de choisir le répertoire windows\system).

Une autre opération importante dans l'onglet Link consiste à proposer à l'éditeur de lien des librairies dans lesquelles il pourra puiser le code de fonctions Tcl et Tk que vous aller solliciter dans votre code (voir plus loin). Ces librairies sont propres au langage Tcl/Tk et permettent d'exploiter toutes les fonctions internes du système Tcl/Tk dans votre code. Deux librairies sont nécessaires, tcl80vc.lib et tk80vc.lib, qui contiennent respectivement les fonctions de la version 8.0p2 de Tcl et Tk. Ces librairies (compatibles avec Visual C++) sont à télécharger en cliquant ici (fichier library.zip comprimé de 53 Ko). Vous devez ensuite les décomprimer dans le répertoire contenant votre source.

Le nom complet des librairie (avec leur chemin) est à fournir dans la zone de texte Object/library modules comme le montre la figure ci-dessous (les noms des différentes librairies sont séparés par un espace et faites attention de ne pas effacer l'intituler de librairies déjà désignées) :

Ne modifiez rien d'autre et cliquez sur OK pour sortir de la boite de dialogue Project Settings.

Procédons à la compilation. Sélectionnez tout d'abord la fenêtre du fichier qtis1.cpp (qui doit donc être ouverte !), puis, depuis le menu Build, lancez la commande Compile qtis1.cpp. L'opération ne dure que quelques secondes. Si vous avez 0 errors et 0 warning, c'est que tout va bien. Dans le cas contraire VC++ indique où se trouve le problème. Corrigez et relancez la compilation.

 

                (3/6)