Pour comprendre de quoi il s'agit il est préférable d'avoir lu cette page.
J'imagine ici que j'ai l'intention d'écrire un bout de code qui utilise C++WinRT mais sans interface graphique. Cela peut être le cas si je veux faire un test par exemple. Je souhaite pourtant utiliser un projet Visual Studio pour pouvoir gentiment travailler dans l'environnement de travail (debug par exemple). Que faire? Refaire ce que nous avions fait dans l'article précédent n'est pas entièrement satisfaisant. En effet, déshabiller un projet C++/CX & XAML laisse des ressources sur le disque (les images .png) que l'on utilisera jamais. En plus, il doit y avoir 12 millions de paramètres positionnés pour nous et dont on ne sait rien. Bref, partir de zéro nous permettra de bien comprendre le processus du Build et de maîtriser les fichiers ainsi que leur organisation sur le disque. Allez c'est parti.
J'ouvre Visual Studio. Ensuite CTRL+SHIFT+N
et je choisis Templates/Visual C++/Empty Project
. Je vous laisse choisir le nom du fichier et l'endroit où vous allez le sauvegarder.
Bon normalement cela ne doit pas prendre trois heures... À droite dans le répertoire Source Files
, je clique droit et je choisis Add
puis New Item...
Là je demande à ajouter un fichier cpp que je nomme MyApp.cpp
. Ensuite je vais suivre la même procédure (ou j'utilise CTRL+SHIFT+A
pour aller plus vite) et j'ajoute un fichier header que je nome pch.h
et un fichier source que je nomme pch.cpp
. À la fin l'arborescence ressemble à ceci :
On va commencer par le plus simple et régler la précompilation des fichiers header. En effet il ne faut pas oublier que cppwinrt est entièrement basé sur des fichiers header et qu'on a donc intérêt à éviter de tout compiler à chaque fois. À gauche, dans Solution Explorer je clique donc sur le nom du projet puis j'appuie sur ALT+ENTER
. La fenêtre des propriétés du projet apparaît à l'écran. Je vais dans C/C++
puis dans Precompiled Header
.
Là je fais bien attention à ce que les listes en haut soient positionnées sur All Configurations
et sur All Platforms
.
Ensuite je vais dans C/C++
et je clique sur Precompiled Header
. Là je fais en sorte que :
- l'option
Precompiled Header
soit surUse (/Yu)
- l'option
Precompiled Header File
pointe sur le fichierpch.h
.
Voir ci-dessous :
Dans le fichier pch.cpp
il suffit ensuite de copier la ligne de code suivante :
#include "pch.h"
Quand c'est fait, je vais sur le fichier pch.cpp
, je clique dessus et j'appuie sur ALT+ENTER
pour faire apparaître la boîte de propriétés. Je fais bien attention à ce que les listes en haut soit sur All Configurations
et sur All Platforms
.
Ensuite je vais dans C/C++
et je clique sur Precompiled Header
et je fais en sorte que :
- l'option
Precompiled Header
soit surCreate (/Yc)
- l'option
Precompiled Header File
pointe sur le fichierpch.h
.
Voir ci-dessous :
En cas de doute sur ces histoires de fichiers précompilés allez jeter un oeil sur cette page.
Bon allez, on passe à la suite. Là on va pas perdre de temps et on va faire du copier coller. Allez dans le répertoire Samples
de cppwinrt. Normalement il est dans ../cppwinrt/10.0.14393.0/Samples
. Là vous allez dans le répertoire Syndication
et vous ouvrez dans Notepad le fichier Main.cpp
. Quand vous l'avez sous les yeux vous faites un bon vieux CTRL+A
puis CTRL+C
et vous retournez dans Visual Studio et vous copiez le code dans MyApp.cpp
. Histoire d'assurer voilà le code :
#include "pch.h" using namespace winrt; using namespace Windows::Foundation; using namespace Windows::Web::Syndication; IAsyncAction Sample() { Uri uri(L"http://kennykerr.ca/feed"); SyndicationClient client; SyndicationFeed feed = co_await client.RetrieveFeedAsync(uri); for (SyndicationItem item : feed.Items()) { hstring title = item.Title().Text(); printf("%ls\n", title.c_str()); } } int main() { initialize(); Sample().get(); }
Encore une fois, je ne vais pas ici expliquer le code car ce n'est pas l'objet de l'article. Moi ce que je veux c'est compiler 🙂
Quand c'est fait, on fait la même chose avec le contenu du fichier ../cppwinrt/10.0.14393.0/Samples/Syndication/pch.h
que l'on colle dans notre fichier pch.h
. Voilà le contenu du ficher en question :
#pragma once #pragma comment(lib, "windowsapp") #include "winrt/Windows.Foundation.h" #include "winrt/Windows.Web.Syndication.h"
Là, normalement on voit déjà qu'il y a un problème. En effet, notre code fait des vagues...
Si on approche le curseur des vaguelettes rouge, Visual nous dit qu'il ne sait pas comment pointer sur winrt/Windows.Web.Syndication.h
Ça, ça sent le problème de chemin d'accès aux fichiers include qu'on a déjà vu la fois précédente. Je vais donc aller un peut plus vite ici
- Clic sur le nom du projet
ALT+ENTER
All Conf
&All Platforms
C/C++
General
Additional Include Directories
doit pointer sur un truc du style "blablabla\cppwinrt\cppwinrt\10.0.14393.0
"- On en profite pour mettre le
Warning Level
à 4
Voir ci-dessous :
On clique sur Appliquer
puis sur OK
et on revient dans l'éditeur. Normalement il n'y a plus de vagues sous les include
. Si on ouvre le fichier MyApp.cpp
là on trouve d'autres vagues sous co_wait
par exemple. Ça, ça doit me faire penser que je doit utiliser des options expérimentales du compilateur (voir article précédent) pour compiler les sources. Là aussi je vais me permettre d'aller plus vite :
- Clic sur le projet
ALT+ENTER
All Conf
&All Platforms
C/C++
Command Line
- Là je tape :
/await /std:c++latest
Voir ci-dessous :
On clique sur Appliquer
puis sur OK
et on revient dans l'éditeur.
Bonne nouvelle. À ce stade on peut compiler le code MyApp.cpp
. Allez, j'appuie sur CTRL+F7
. Normalement ça doit compiler sans erreur.
Bon allez on va générer l'exécutable... J'appuie sur CTRL+SHIFT+B
et là ça part en vrille ! Il y a deux messages d'erreur (Faut pas hésiter à cliquer sur l'image ci-dessous si c'est pas lisible)
Ce qui me fait tiquer c'est le message concernant windowsapp.lib
. Allez, on retourne dans les propriétés du projet et là je vais dans General
(tout en haut de la boite de dialogue). À droite j'observe que l'option Target Platform Version
est fixé à 8.1
. Je déroule la liste box et je choisi 10.0.14393.0
. Je clique sur OK
et de retour dans l'éditeur je relance une compilation et une édition de lien en appuyant sur CTRL+SHIFT+B
. Et là tout roule !
Je pose un point d'arrêt sur la ligne 18 (printf()
) et le lance le code en appuyant sur F5
. Après je m'amuse et je clique sur F10
pour circuler dans la boucle. Que du bonheur.
Remarque
Si je lance le code sans point d'arrêt, la console disparaît tout de suite et je ne vois rien. Pour corriger cela je propose de modifier le code comme suit :
#include "pch.h" using namespace winrt; using namespace Windows::Foundation; using namespace Windows::Web::Syndication; using namespace std; IAsyncAction Sample() { Uri uri(L"http://kennykerr.ca/feed"); SyndicationClient client; SyndicationFeed feed = co_await client.RetrieveFeedAsync(uri); for (SyndicationItem item : feed.Items()) { hstring title = item.Title().Text(); printf("%ls\n", title.c_str()); } } int main() { initialize(); Sample().get(); cout << "Press ENTER to quit : "; cin.ignore((numeric_limits<streamsize>::max)(), '\n'); }
Bien sûr pour utiliser std::cout
il faut modifier pch.h
comme suit :
#pragma once #pragma comment(lib, "windowsapp") #include "winrt/Windows.Foundation.h" #include "winrt/Windows.Web.Syndication.h" #include <iostream>
Si on lance le build, tout devrait bien se passer et voilà ce que l'on observe :
Il faut remarquer que Visual est obligé de recompiler le fichier pch.cpp
car on a modifié le contenu de pch.h
.
Finalement, puisque iostream.h
est dans le projet autant en profiter pour virer le printf()
de la boucle for
et de ré-écrire cette dernière comme suit :
for (SyndicationItem item : feed.Items()) { hstring title = item.Title().Text(); wcout << title.c_str() << "\n"; }
Si on lance un dernier Build voilà ce que l'on obtient en sortie :
On observe bien que Visual ne compile que MyApp.cpp
et plus pch.cpp
. On a donc la preuve que notre configuration du fichier header précompilé fonctionne bien.
Allez, je crois que c'est bon pour ce soir. A plus.
Leave a Reply