TP1: Programmation et tests win32 sous GNU/Linux
Hello world pour Win32
Comparez ce programme avec le classique "Hello world" en C sous Unix:
source:/ensta/tp1/hello/hello32.c
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
MessageBox(NULL, "Hello world !", "hello32 example", MB_OK);
return 0;
}
Pour compiler ce programme, on utilise pratiquement la même recette:
source:/ensta/tp1/hello/Makefile
# Avec Debian, utiliser "apt-get mingw32" pour obtenir le cross-compilateur
WINCC=i586-mingw32msvc-gcc
CC=gcc
hello32.exe: hello32.c
$(WINCC) -o $@ $<
hello: hello.c
$(CC) -o $@ $<
clean:
rm hello hello32.exe
On peut alors tester ce programme à l'aide de Wine:
$ wine ./hello32.exe
Abstraction et portage
On commence par identifier les services "haut niveau" requis par le programme. Considérons par exemple le programme "Hello world" expurgé des fonctions trop Unixiennes ou Windosiennes :
source:/ensta/tp1/hello-all/hello.c
#include "libhello.h"
void start()
{
hello("Hello world!");
}
On demande implcitement deux choses: un "guichet unique" comme point d'entrée (start()), et une fonction qui affiche un message (hello()) - que ce soit via une console ou une fenêtre de dialogue. En C, l'interface représentant ces besoins s'écrit ainsi:
source:/ensta/tp1/hello-all/libhello.h
#ifndef _libhello_h_ #define _libhello_h_ /* Cette fonction est a definir et sera le point de depart du programme */ extern void start(); /* Affiche un message court a l'utilisateur */ void hello(const char* message); #endif /* _libhello_h_ */
Il nous suffit alors d'implémenter cette interface pour chaque plateforme: voir source:/tp1/hello-all/libhello-unix.c et source:/tp1/hello-all/libhello-win32.c
On constate en pratique que la partie spécifique aux plateformes d'un logiciel portable représente une faible partie (ex: moins de 10% chez Apache, Mozilla ou OpenOffice?.org). Ceci permet de séparer les problèmes (programmer l'application d'un côté, la rendre portable de l'autre).
