Index du site
Google

Outils pour programmer Windows en C

Il existe de nombreuses façons de programmer, certains préfèrent un environnement de développement intégré ou IDE, d'autres assemblent leur propre boite à outils à partir d'éléments hétérogènes, payants ou pas. Il y a moyen d'en rajouter (contrôle de version, bibliothèques spécialisées, etc.) mais le kit minimum se trouve là, sous notre pointeur de souris, prêt à nous rendre service, à condition de nous retrousser les manches pour installer puis mettre à jour les éléments en question. Voici donc une solution viable, éprouvée, évolutive et gratuite.

haut de page  Le compilateur

Introduction

Nous parlons souvent, pour gagner du temps, du compilateur. En réalité il s'agit de tout un environnement comprenant outre le compilateur, l'éditeur de liens, le débogueur, les bibliothèques, les fichiers d'en-tête, etc. Le code source de ce site est destiné à être compilé directement par les outils de MinGW, une version Windows des outils GNU (gcc, gdb, make, etc.) (oui, GNU est un acronyme récursif). Si vous souhaitez compiler les programmes avec d'autres outils, il vous faudra retailler le code, en particulier le makefile qui risque de ne pas convenir.

Nous parlons ici d'une étape cruciale de l'installation de votre environnement de travail, aussi nous allons la détailler. Les téléchargements se font depuis SourceForge.net, une énorme plateforme de développement hébergeant des milliers de projets en cours de réalisation dont MinGW.

Installation-type

Nous allons sur le site de MinGW, et cliquons sur le lien télécharger (lien "Download") qui nous mène à la page des téléchargements de MinGW. De là, un lien spécifique vers la nébuleuse SourceForge va nous amener dans une page contenant un tableau listant les packages du projet MinGW. Si ce lien n'est plus valide, merci de me le signaler en m'envoyant un email à contact@toutenc.com pour que je le corrige.

À partir de là, nous avons deux possibilités, qui ne s'excluent pas (dans l'optique des mises à jour par exemple): soit nous téléchargeons le "Automated MinGW Installer" qui se charge d'installer tout le contexte pour nous, soit (ce qui revient presque au même) nous téléchargeons nous-mêmes les packages dont nous aurons besoin.

Important: le répertoire principal de MinGW sera, c'est très vivement conseillé, C:\mingw\. Par voie de conséquence, après installation de MinGW et/ou dépliage des archives, celui des fichiers d'en-tête sera C:\mingw\include\, celui des bibliothèques C:\mingw\lib\, etc.

Pour une première installation, nous favoriserons la solution du "Automated MinGW Installer" (MinGW-....exe), un installateur dont le comportement est habituel pour l'utilisateur Windows, et qui se chargera de tout, en particulier de modifier une certaine variable d'environnement que les plus anciens connaissent, le PATH (chemin) qui va permettre à "Invite de commandes" (ex-DOS) de trouver les exécutables (gcc.exe, mingw32-make.exe, gdb.exe, etc.).

Installation manuelle ou mise à jour

Si nous installons les packages à la main la première fois, il nous faudra modifier le PATH sous Windows XP par le "Panneau de configuration" > "Système" > onglet "Avancé" > bouton "Variables d'environnement" (ouf) en ajoutant le chemin C:\mingw\bin\. Par la suite, la mise à jour se fera sur un ordinateur en principe déjà configuré.

Notons que les archives sont au format "tar.gz" que WinZip sait extraire, en deux temps (il demandera le droit de se servir d'un répertoire temporaire - répondre oui). Toutes les archives doivent être dépliées en partant de C:\mingw\, le répertoire d'installation préférentiel de MinGW. Voici les archives dont nous aurons besoin:

Bon...

Ce qui précède est un peu fastidieux, et il faudra le refaire pour mettre à jour les outils, mais c'est finalement assez facile avec un peu d'habitude. Bien qu'ils soient gratuits, la qualité des logiciels issus du monde GNU justifie largement que nous mettions les mains dans le cambouis. Et puis dans le fond, savoir installer sa boite à outils, comprendre ce qu'il y a dedans, apprendre à programmer Windows en langage C... Cela risque de faire de vous un expert (si ce n'est pas déjà le cas) alors accrochez-vous, cela en vaut la peine !

haut de page  L'éditeur de texte

Un éditeur de texte (à ne pas confondre avec un traitement de texte) permet d'écrire du code source au format texte brut, en effectuant des raccourcis clavier, des annulations multiples, des copier-coller, des remplacements efficaces sur plusieurs fichiers, etc. Une fois paramétré, un éditeur nous autorise à piloter le compilateur et le débogueur en liaison directe avec le code source.

La caractéristique la plus visible d'un éditeur de texte, et peut-être la plus importante, est la coloration syntaxique. Il est vital, pour ne pas s'user les yeux et le cerveau, de taper du code (C, html, php, css, etc.) dans une fenêtre qui colore les mots-clés, commentaires et autres chaînes de caractères, dans des couleurs qui sautent aux yeux.

Il existe de nombreux éditeurs de texte gratuits. Citons SciTE, Crimson Editor, et les deux poids lourds issus du monde Unix et capables de presque tout à part vous faire du café, je veux parler de Vim et Emacs.

Un mot sur la configuration des outils dans Crimson Editor: dans le menu "Tools", choisissez "Preferences" ou "Config. User Tools" et saisissez le chemin et le nom du logiciel mingw32-make ainsi que les arguments et le répertoire initial. Sur l'image ci-dessous, la configuration permettra de compiler le programme à partir de l'éditeur en cliquant Ctrl+1, à condition d'avoir ouvert un makefile sans erreur dans Crimson Editor et de se trouver dedans. Dans l'exemple présenté, l'environnement MinGW est installé dans le répertoire C:\mingw\: veillez à adapter si besoin à votre cas de figure si le répertoire d'installation sur votre ordinateur est différent. Pensez aussi à cocher "capture output" ce qui vous permettra de lire les messages d'erreur et autres warnings dans l'éditeur. Cliquez pour agrandir
Cliquez pour agrandir

Quoi qu'il en soit, prenez l'éditeur de texte qui vous plaît, et entraînez-vous au clavier à sélectionner des mots, des lignes, à faire des couper-copier-coller, à déplacer le curseur de mot en mot, à faire des rechercher-remplacer, à le configurer pour effectuer des tâches spécifiques, etc.

haut de page  Le débogueur

Introduction

Nous allons nous limiter à un exemple simple, les tutoriels sur gdb ne manquent pas et aller plus loin demanderait plusieurs pages. gdb fait quatre types de travaux en théorie:

Supposons que notre programme soit tec003.exe (onglet Contrôles > Edit). Nous le compilons avec dans le makefile l'option -g qui génère un code enrichi d'une table de symboles, ce qui permet à gdb d'avoir des indicateurs sur le programme pendant son exécution.

Sous "Invite de commandes" Invite de commandes (Démarrer > Tous les programmes > Accessoires) nous naviguons à l'aide de commandes cd (change directory ou changer de répertoire) jusqu'à nous trouver dans le répertoire où se trouve tec003. Puis nous entrons les commandes gdb tec003 et run.

Le programme tec003 est démarré par gdb et il se déroule comme si gdb n'était pas là (ou un peu moins vite). Si le programme ne plante pas, si nous n'avons pas déclaré de point d'arrêt (breakpoint), la session de tec003 se passe normalement. Si pour une raison ou une autre un problème bloquant survient, gdb arrête le programme et nous présente un bilan.

Nous pouvons obtenir de l'aide de gdb par la commande help éventuellement suivie d'une catégorie de commandes, par exemple help stack pour la pile, et gdb s'arrête par la commande quit.

Problème

Nous allons maintenant générer une erreur volontairement, toujours dans le programme tec003 (qui rappelons-le se trouve dans l'onglet Contrôles > Edit), au niveau de l'allocation de mémoire dans le fichier source tec003.c:

sTemp = malloc ((1 + lResult) * sizeof(TCHAR));
if (NULL == sTemp) {
    msgb(CH_ERREUR_ALLOC);
    break;
}

Cette allocation de mémoire est censée fournir assez de place pour récupérer les lResult caractères contenus dans un contrôle d'édition, pour ensuite les copier dans un autre contrôle d'édition. Remplaçons le code ci-dessus par ceci:

/* (Original) sTemp = malloc ((1 + lResult) * sizeof(TCHAR));
if (NULL == sTemp) {
    msgb(CH_ERREUR_ALLOC);
    break;
} */

Le bloc de code original n'est pas retiré, il est mis en commentaire, ce qui a pour effet de le rendre inactif: la mémoire n'est pas allouée, mais le code est toujours syntaxiquement correct, il va compiler donc à ce stade nous ne verrons rien du problème. Seulement là, nous sommes certains de manquer de place car sTemp ne pointe pas vers un emplacement alloué par le programme, il est même déclaré et initialisé à NULL en début de fonction.

Compilons le programme altéré, toujours en mode débogage (option -g), et lançons tec003 à travers gdb par les commandes habituelles: gdb tec003 puis run. Au moment où nous essayons de copier les caractères d'un contrôle d'édition dans un autre, tec003 essaie de faire entrer les caractères dans un pointeur NULL, d'où un plantage et voici la séquence qui suit:

1. gdb suspend l'activité de tec003 et rapporte un signal de violation de segment mémoire, envoyé par Windows à l'application:

gdb violation de segment

2. Nous saisissons la commande bt ou backtrack, donc gdb liste les éléments de la pile d'appel de fonctions (stack) et au "#9" il nous donne le nom du fichier source, le nom de la fonction et le numéro de la ligne dans laquelle se trouve le problème:

gdb la ligne incriminée

3. Nous demandons à gdb d'examiner le contenu du pointeur sTemp dans la fonction WndProc, il nous confirme que ce pointeur est NULL (adresse 0x0):

gdb confirmation pointeur NULL

Voici la ligne 70 dans le fichier source, c'est celle sur laquelle nous demandons à Windows de faire entrer le texte du contrôle hEdit1 dans le pointeur de caractères sTemp, ce qui fait planter le programme - normal, car nous avons volontairement laissé sTemp à NULL:

SendMessage(hEdit1, WM_GETTEXT, (WPARAM) (1 + lResult), (LPARAM) sTemp);

Il ne nous reste plus qu'à arrêter tec003 depuis gdb par la commande kill en confirmant (y) puis à arrêter gdb lui-même par la commande quit.

Breakpoint

Nous avons maintenant réactivé l'allocation de mémoire correctement en enlevant les mises en commentaire /* */ et recompilé l'application qui tourne apparemment sans encombre. Rien ne nous empêche de placer un point d'arrêt ou breakpoint juste après l'endroit qui posait problème, histoire de surveiller que tout se passe bien. Nous démarrons gdb par la commande gdb tec003 puis réglons le breakpoint par une autre commande, break tec003.c:71:

gdb réglage breakpoint

Si gdb répond "no symbol table is loaded", cela signifie que nous avons omis de compiler avec l'option "-g", il faut donc recompiler avec cette option.

Ensuite nous démarrons tec003 à travers gdb par run. La copie du contenu de hEdit1 dans hEdit2 aboutit au breakpoint, et gdb arrête tec003. Examinons à titre d'exemple la valeur de lResult, le retour de la fonction qui mesure le nombre de caractères du texte de hEdit1 (ici nous avons saisi abc):

gdb réglage breakpoint

Nous entrons la commande continue qui permet à tec003 de fonctionner à nouveau, et nous quittons tec003 (Alt+F4). Enfin nous arrêtons gdb par la commande quit.

Bien entendu, nous aurions pu demander à gdb d'afficher le contenu du pointeur de caractères sTemp (il aurait sans doute répondu "abc") mais pour le moment gdb ne gère pas les caractères Unicode.

[màj 9 octobre 2007]

Copyright © 2008 B. Challier • légalcontact Valid XHTML 1.0 Valid CSS 2haut