Blog ENI : Toute la veille numérique !
Dernière chance (fin le 29/02) : -25€ dès 75€ sur les livres en ligne, vidéos... code FUSEE25. J'en profite !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. C++
  3. Les univers de C++
Extrait - C++ Des fondamentaux du langage aux applications (3e édition)
Extraits du livre
C++ Des fondamentaux du langage aux applications (3e édition) Revenir à la page d'achat du livre

Les univers de C++

L’environnement Windows

1. Les programmes Win32

La plate-forme Win32 a très vite été supportée par C++ car Microsoft a lancé dès 1992 l’un des premiers environnements intégrés pour ce langage ; il s’agissait de Visual C++, et à cette époque, de nombreux architectes étaient convaincus de l’intérêt d’un langage objet proche du langage C pour créer des applications fonctionnant dans des environnements graphiques.

Toutefois, la programmation d’une application fenêtrée, sans framework, n’est pas une tâche aisée. Il n’en demeure pas moins que la plateforme Win32 propose plusieurs formats d’applications : applications "console", services Windows, bibliothèques dynamiques (DLL) et bien entendu les applications graphiques fenêtrées.

Il n’existe pas de modèle de projet "Win64" car Windows reste un système très ancré dans le mode 32 bits. Toutefois, Visual Studio sait compiler en mode 64 bits depuis un projet Win32.

2. Choix du mode de compilation

La création d’un projet s’effectue avec la commande Fichier - Nouveau Projet :

images/05RI01.png

Depuis le Gestionnaire de configurations, le mode de compilation 64 bits est activé :

images/05RI02.png

Le programme qui suit est intéressant ; il indique que la taille des types int et long est identique à un mode 32 bits.

printf("Programme compilé en mode 64 bits\n"); 
printf("taille int %d\n", sizeof(int)); 
printf("taille long %d\n", sizeof(long)); 
images/05RI03.png

Le mode 64 bits recommande au compilateur de produire des instructions microprocesseur 64 bits, mais cela ne veut pas dire que les types sont ajustés en conséquence. Autrement dit, un calcul sur un type __int64 pourra prendre plus de temps en 32 bits qu’en 64, mais __int64 reste toujours 64 bits et int reste sur 4 octets quel que soit le mode de compilation. Il s’agit là d’une particularité du compilateur de Microsoft ; d’autres compilateurs peuvent adopter un comportement différent.

3. Fonctionnement des applications fenêtrées Win32

Il n’y a pas de différence structurelle entre l’exécutable console et le desktop. Ce sont des appels système qui déclenchent...

L’environnement .NET

1. Le code managé et la machine virtuelle CLR

Comme Java, .NET fait partie de la famille des environnements virtualisés. Le compilateur C++ managé ne produit pas du code assembleur directement exécuté par le microprocesseur mais un code intermédiaire, lui-même exécuté par une machine "virtuelle", la CLR (Common Language Runtime). Cette couche logicielle reproduit tous les composants d’un ordinateur - mémoire, processeur, entrées-sorties…

Cette machine doit s’adapter au système d’exploitation qui l’héberge, et surtout optimiser l’exécution du code.

Il y a là une différence importante entre .NET et Java. Alors que Microsoft a évidemment fait le choix de se concentrer sur la plate-forme Windows, d’autres éditeurs ont porté Java sur leurs OS respectifs - Unix, AIX, Mac OS, Linux… La société Novell a cependant réussi le portage de .NET sur Linux, c’est le projet Mono.

Cet environnement virtualisé a une conséquence très importante sur les langages supportés ; les types de données et les mécanismes objets sont ceux de la CLR. Comme Microsoft était dans une démarche d’unification de ses environnements, plusieurs langages se sont retrouvés éligibles à la CLR, quitte à adapter un peu leur définition. Le projet de Sun était plutôt une création ex nihilo, et de ce fait seul le langage Java a réellement été promu sur la machine virtuelle JVM.

2. Les adaptations du langage C++ CLI

Le terme CLI signifie Common Language Infrastructure ; c’est l’ensemble des adaptations nécessaires au fonctionnement de C++ pour la plate-forme .NET / CLR.

a. La norme CTS

Le premier changement concerne les types de données. En successeur de C, le C++ standard a basé sa typologie sur le mot machine (int) et le caractère de 8 bits (char). Confronté à des problèmes de standardisation et d’interopérabilité, Microsoft a choisi d’unifier les types de données entre ses différents langages.

Les types primitifs, destinés à être employés comme variables...

Travaux pratiques

1. Réaliser une application de dessin Win32

Nous reprenons le format d’application Win32 étudié en début de chapitre pour réaliser un programme capable d’afficher deux types de dessins générés par calcul C++.

Notre projet s’appelle "C++ Win UI".

La première étape consiste à ajouter de nouvelles entrées Affichage - Surface et Affichage - Fractale au menu de l’application. Pour cela, il faut ouvrir le fichier de ressource et éditer le menu IDC_CWINUI :

images/05NEWRI09.png

Le caractère souligné sert de raccourci-clavier (on dit aussi accélérateur). Il s’obtient en précédant la lettre A (puis respectivement S et F) par un signe &.

Pour désigner chaque type de dessin, on définit une énumération dans le fichier C++ WinUI.cpp :

enum Affichage { Surface, Fractale } affichage; 

La fonction wWinMain() se substitue à la traditionnelle fonction main(). C’est un emplacement possible pour initialiser la variable affichage :

int APIENTRY wWinMain(_In_ HINSTANCE hInstance, 
                    _In_opt_ HINSTANCE hPrevInstance, 
                    _In_ LPWSTR    lpCmdLine, 
                    _In_ int       nCmdShow) 
{ 
   UNREFERENCED_PARAMETER(hPrevInstance); 
   UNREFERENCED_PARAMETER(lpCmdLine); 
 
   // TODO: Placez le code ici. 
   affichage = Affichage::Surface; 

La fonction WndProc() traite les messages de l’application. À chaque entrée dans le menu correspond une action de WM_COMMAND :

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
   switch (message) 
   { 
       case WM_COMMAND: 
       { 
           int wmId = LOWORD(wParam); 
           // Analyse les sélections de menu : 
           switch (wmId) 
           { 
       ...