Applications Windows
Réduire la table des matières
Développer la table des matières

Procédure pas à pas : création d'un composant Windows Runtime de base en C++ et appel de ce composant depuis JavaScript ou C#

 

Date de publication : avril 2016

Cette procédure pas à pas montre comment créer une DLL de composant Windows Runtime de base qui peut être appelée à partir de JavaScript, C# ou de Visual Basic. Avant de commencer cette procédure pas à pas, assurez-vous de comprendre les concepts tels que l'interface binaire abstraite (ABI), les classes ref et les extensions de composants Visual C++ qui facilitent l'utilisation des classes ref. Pour plus d’informations, consultez Création de composants Windows Runtime en C++ et Informations de référence sur le langage Visual C++ (C++-CX).

Dans cet exemple, nous commençons par créer le projet du composant, mais vous pouvez très bien créer le projet JavaScript en premier. L'ordre n'a pas d'importance.

Notez que la classe principale du composant contient des exemples de propriété et de définitions de méthode, ainsi qu'une déclaration d'événement. Ces éléments sont fournis uniquement pour vous montrer le fonctionnement. ils ne sont pas obligatoires, et dans cet exemple, nous remplacerons le code généré par notre propre code.

Pour créer le projet de composant C++

  1. Dans la barre de menus de Visual Studio, choisissez Fichier, Nouveau, Projet.

  2. Dans la boîte de dialogue Nouveau projet, dans le volet gauche, développez Visual C++, puis sélectionnez le nœud pour les applications Windows Store.

  3. Dans le volet central, sélectionnez Composant Windows Runtime, puis nommez le projet WinRT_CPP.

  4. Sélectionnez le bouton OK.

Pour ajouter une classe activable au composant

  1. Une classe activable est une classe que le code client peut créer à l'aide d'une expression new (New en Visual Basic, ou ref new en C++). Dans votre composant, vous devez la déclarer comme public ref class sealed. En fait, les fichiers Class1.h et .cpp ont déjà une classe de référence. Vous pouvez modifier le nom, mais dans cet exemple nous utiliserons celui par défaut : Class1. Vous pouvez définir des classes ref ou standard supplémentaires dans votre composant si elles sont requises. Pour plus d'informations sur les classes ref, consultez Système de type (C++/CX).

Pour ajouter les directives #include requises

  • Ajoutez ces directives #include à Class1.h:

    collection.h est le fichier d'en-tête pour les classes concrètes C++, telles que la Platform::Collections::Vector, classe et la Platform::Collections::Map, classe, qui implémentent des interfaces indépendantes du langage définies par Windows Runtime. Les en-têtes amp sont utilisés pour exécuter des calculs sur le GPU. Ils n'ont pas d'équivalent dans Windows Runtime, et cela ne pose pas de problème, car ils sont privés. En général, pour des raisons de performance vous devez utiliser du code C++ ISO et des bibliothèques standard en interne dans le composant ; seule l'interface Windows Runtime doit être exprimée en types Windows Runtime.

Pour ajouter un délégué à la portée espace de noms

  1. Un délégué est une construction qui définit les paramètres et le type de retour pour les méthodes. Un événement est une instance d'un type délégué particulier, et toute méthode de gestionnaire d'événements qui s'abonne à l'événement doit avoir la signature spécifiée dans le délégué. Le code suivant définit un type délégué qui accepte un int et retourne void. Ensuite, le code déclare un event public de ce type ; cela permet au code client de fournir des méthodes qui sont invoquées lorsque l'événement est déclenché.

    Ajoutez la déclaration delegate suivante à la portée espace de noms dans Class1.h, juste avant la déclaration Class1.

    System_CAPS_tipAstuce

    Si le code ne s'aligne pas correctement lorsque vous le collez dans Visual Studio, appuyez sur Ctrl+K+D pour corriger la mise en retrait pour le fichier complet.

Pour ajouter les membres publics

  1. La classe expose trois méthodes publiques et un événement public. La première méthode est synchrone, car elle s'exécute toujours très rapidement. Étant donné que les deux autres méthodes peuvent prendre un certain temps, elles sont asynchrones afin de ne pas bloquer le thread d'interface utilisateur. Ces méthodes retournent IAsyncOperationWithProgress et IAsyncActionWithProgress. Le premier définit une méthode asynchrone qui retourne un résultat, et le second définit une méthode asynchrone qui retourne void. Ces interfaces permettent également au code client de recevoir des mises à jour sur la progression de l'opération.

Pour ajouter les membres privés

  1. La classe contient trois membres privés : deux méthodes d’assistance pour les calculs numériques et un objet CoreDispatcher utilisé pour marshaler les appels d’événements des threads de travail vers le thread d’interface utilisateur.

Pour ajouter les directives d'en-tête et d'espace de noms

  1. Dans Class1.cpp, ajoutez ces directives #include :

  2. Ajoutez ensuite ces instructions using pour récupérer les espaces de noms requis :

Pour ajouter l'implémentation pour ComputeResult

  1. Dans Class1.cpp, ajoutez l'implémentation de méthode suivante. Cette méthode s'exécute de façon synchrone sur le thread appelant, mais elle est très rapide, car elle utilise C++ AMP pour paralléliser le calcul sur le GPU. Pour plus d'informations, consultez Présentation de C++ AMP. Les résultats sont ajoutés à un type concret Platform::Collections::Vector<T>, qui est implicitement converti en un Windows::Foundation::Collections::IVector<T> quand il est retourné.

Pour ajouter l'implémentation pour GetPrimesOrdered et sa méthode d'assistance

  1. Dans Class1.cpp, ajoutez les implémentations pour GetPrimesOrdered et la méthode d'assistance is_prime.GetPrimesOrdered utilise Classe concurrent_vector et une boucle parallel_for, fonction pour diviser le travail et pour utiliser les ressources maximales de l'ordinateur sur lequel le programme s'exécute pour produire des résultats. Une fois que les résultats sont calculés, stockés et triés, ils sont ajoutés à Platform::Collections::Vector<T> et retournés en tant que Windows::Foundation::Collections::IVector<T> au code client.

    Notez le code du rapporteur de progression, qui permet au client de connecter une barre de progression ou toute autre interface utilisateur permettant à l'utilisateur de voir combien de temps l'opération va encore prendre. Le rapport de progression a un coût. Un événement doit être déclenché du côté du composant et géré sur le thread d'interface utilisateur, et la valeur de progression doit être stockée à chaque itération. Un moyen de réduire le coût consiste à limiter la fréquence à laquelle un événement de progression est déclenché. Si le coût est encore excessif, ou si vous ne pouvez pas estimer la longueur de l'opération, envisagez d'utiliser une boucle de progression ; elle indique qu'une opération est en cours sans afficher le temps restant jusqu'à la fin.

Pour ajouter l'implémentation pour GetPrimesUnordered

  1. La dernière étape pour créer le composant C++ consiste à ajouter l'implémentation pour GetPrimesUnordered dans Class1.cpp. Cette méthode retourne chaque résultat dès qu'il est trouvé, sans attendre que tous les résultats soient trouvés. Chaque résultat est retourné dans le gestionnaire d'événements et affiché dans l'interface utilisateur en temps réel. Là encore, notez qu'un rapporteur de progression est utilisé. Cette méthode utilise également la méthode d'assistance is_prime.

  2. Appuyez sur Ctrl+Shift+B pour générer le composant.

Pour créer un projet JavaScript

  1. System_CAPS_noteRemarque

    Si vous souhaitez simplement créer un client C#, vous pouvez ignorer cette section.

    Dans l'Explorateur de solutions, ouvrez le menu contextuel du nœud Solution et sélectionnez Ajouter, Nouveau projet.

  2. Développez JavaScript (il peut être imbriqué sous Autres langages) et choisissez Application vide.

  3. Acceptez le nom par défaut, App1, en cliquant sur le bouton OK.

  4. Ouvrez le menu contextuel du nœud de projet App1, puis sélectionnez Définir comme projet de démarrage.

  5. Ajoutez une référence de projet à WinRT_CPP :

    1. Ouvrez le menu contextuel du nœud Références et sélectionnez Ajouter une référence.

    2. Dans le volet gauche de la boîte de dialogue Gestionnaire de références, sélectionnez Solution, puis Projets.

    3. Dans le volet central, sélectionnez WinRT_CPP, puis cliquez sur le bouton OK.

Pour ajouter le code HTML qui appelle les gestionnaires d'événements JavaScript

  1. Collez ce code HTML dans le nœud <body> de la page default.html :

Pour ajouter des styles

  1. Dans default.css, supprimez le style body, puis ajoutez ces styles :

    
    #LogButtonDiv { border: orange solid 1px; -ms-grid-row: 1; /* default is 1 */ -ms-grid-column: 1; /* default is 1 */ } #LogResultDiv { background: black; border: red solid 1px; -ms-grid-row: 1; -ms-grid-column: 2; } #UnorderedPrimeButtonDiv, #OrderedPrimeButtonDiv { border: orange solid 1px; -ms-grid-row: 2; -ms-grid-column:1; } #UnorderedPrimeProgress, #OrderedPrimeProgress { border: red solid 1px; -ms-grid-column-span: 2; height: 40px; } #UnorderedPrimeResult, #OrderedPrimeResult { border: red solid 1px; font-size:smaller; -ms-grid-row: 2; -ms-grid-column: 3; -ms-overflow-style:scrollbar; }
    
    

Pour ajouter les gestionnaires d'événements JavaScript faisant appel à la DLL du composant

  1. Ajoutez les fonctions suivantes à la fin du fichier default.js : Ces fonctions sont appelées lorsque les boutons de la page principale sont sélectionnés. Notez que JavaScript active la classe C++, appelle ensuite ses méthodes, puis utilise des valeurs de retour pour remplir les étiquettes HTML.

  2. Appuyez sur F5 pour exécuter l'application.

La DLL du composant Windows Runtime C++ peut tout aussi facilement être appelée à partir d'un client C# que d'un client JavaScript. Les étapes suivantes montrent comment créer un client C# qui soit pratiquement équivalent au client JavaScript de la section précédente.

Pour créer un projet C#

  1. Dans l'Explorateur de solutions, ouvrez le menu contextuel du nœud Solution, puis sélectionnez Ajouter, Nouveau projet.

  2. Développez Visual C# (il peut être imbriqué sous Autres langages), sélectionnez Windows Store dans le volet gauche, puis Application vide dans le volet central.

  3. Nommez cette application CS_Client, puis cliquez sur le bouton OK.

  4. Ouvrez le menu contextuel du nœud de projet CS_Client, puis sélectionnez Définir comme projet de démarrage.

  5. Ajoutez une référence de projet à WinRT_CPP :

    1. Ouvrez le menu contextuel du nœud Références et sélectionnez Ajouter une référence.

    2. Dans le volet gauche de la boîte de dialogue Gestionnaire de références, sélectionnez Solution, puis Projets.

    3. Dans le volet central, sélectionnez WinRT_CPP, puis cliquez sur le bouton OK.

Pour ajouter le code XAML qui définit l'interface utilisateur

  1. Ajoutez le ScrollViewer suivant et son contenu à la grille dans mainpage.xaml :

    <ScrollViewer> <StackPanel Width="1400"> <Button x:Name="Button1" Width="340" Height="50"  Margin="0,20,20,20" Content="Synchronous Logarithm Calculation" FontSize="16" Click="Button1_Click_1"/> <TextBlock x:Name="Result1" Height="100" FontSize="14"></TextBlock> <Button x:Name="PrimesOrderedButton" Content="Prime Numbers Ordered" FontSize="16" Width="340" Height="50" Margin="0,20,20,20" Click="PrimesOrderedButton_Click_1"></Button> <ProgressBar x:Name="PrimesOrderedProgress" IsIndeterminate="false" Height="40"></ProgressBar> <TextBlock x:Name="PrimesOrderedResult" MinHeight="100" FontSize="10" TextWrapping="Wrap"></TextBlock> <Button x:Name="PrimesUnOrderedButton" Width="340" Height="50" Margin="0,20,20,20" Click="PrimesUnOrderedButton_Click_1" Content="Prime Numbers Unordered" FontSize="16"></Button> <ProgressBar x:Name="PrimesUnOrderedProgress" IsIndeterminate="false" Height="40" ></ProgressBar> <TextBlock x:Name="PrimesUnOrderedResult" MinHeight="100" FontSize="10" TextWrapping="Wrap"></TextBlock> <Button x:Name="Clear_Button" Content="Clear" HorizontalAlignment="Left" Margin="0,20,20,20" VerticalAlignment="Top" Width="341" Click="Clear_Button_Click" FontSize="16"/> </StackPanel> </ScrollViewer>
    

Pour ajouter les gestionnaires d'événements pour les boutons

  1. Dans l'Explorateur de solutions, ouvrez mainpage.xaml.cs. (Le fichier peut être imbriqué sous mainpage.xaml.) Ajoutez une directive using pour System.Text, puis ajoutez le gestionnaire d'événements pour le calcul de logarithme dans la classe MainPage, juste après OnNavigateTo.

  2. Ajoutez le gestionnaire d'événements pour le résultat ordonné :

  3. Ajoutez le gestionnaire d'événements pour le résultat non ordonné, et pour le bouton qui efface les résultats afin de pouvoir exécuter à nouveau le code.

Sélectionnez le projet C# ou le projet JavaScript en tant que projet de démarrage en ouvrant le menu contextuel du nœud de projet dans l'Explorateur de solutions et en sélectionnant Définir comme projet de démarrage. Appuyez ensuite sur F5 pour une exécution avec débogage, ou sur Ctrl+F5 pour une exécution sans débogage.

Dans Explorateur d'objets, vous pouvez examiner tous les types Windows Runtime définis dans les fichiers.winmd. Cela inclut les types de l'espace de noms Platform et l'espace de noms par défaut. Toutefois, étant donné que les types dans l'espace de noms Platform::Collections sont définis dans le fichier d'en-tête collections.h, et non dans un fichier winmd, ils n'apparaissent pas dans Explorateur d'objets.

Pour vérifier le composant

  1. Dans la barre de menus, sélectionnez Afficher, Autres fenêtres, Explorateur d'objets.

  2. Dans le volet gauche de l'Explorateur d'objets, développez le nœud WinRT_CPP pour afficher les types et les méthodes qui sont définis dans votre composant.

Pour optimiser le débogage, téléchargez les symboles de débogage à partir des serveurs de symboles publics de Microsoft :

  1. Dans la barre de menus, sélectionnez Outils, Options.

  2. Dans la boîte de dialogue Options, développez Débogage et sélectionnez Symboles.

  3. Sélectionnez Serveurs de symboles Microsoft, puis cliquez sur le bouton OK.

Le téléchargement des symboles peut prendre un certain temps la première fois. Pour accélérer les performances la prochaine fois que vous appuierez sur F5, spécifiez un répertoire local dans lequel mettre en cache les symboles.

Lorsque vous déboguez une solution JavaScript qui contient une DLL de composant, vous pouvez définir le débogueur pour activer la progression dans le script ou dans le code natif du composant, mais pas les deux à la fois. Pour modifier ce paramètre, ouvrez le menu contextuel du nœud de projet JavaScript dans l'Explorateur de solutions, puis sélectionnez Propriétés, Débogage, Type de débogueur.

Veillez à sélectionner les fonctionnalités appropriées dans le concepteur de packages. Par exemple, si vous essayez d'accéder par programmation à des fichiers du dossier Images, veillez à activer la case à cocher Bibliothèque d'images dans le volet Capacités du concepteur de packages.

Si votre code JavaScript ne reconnaît pas les propriétés ou méthodes publiques du composant, assurez-vous que vous utilisez la casse mixte dans JavaScript. Par exemple, la méthode C++ ComputeResult doit être référencée sous la forme computeResult dans JavaScript.

Si vous supprimez un projet de composant Windows Runtime dans une solution, vous devez également supprimer manuellement la référence de projet dans le projet JavaScript. Sinon, les opérations de débogage ou de génération suivantes ne peuvent pas être effectuées. Si nécessaire, ajoutez ensuite une référence d'assembly à la DLL.

Afficher:
© 2017 Microsoft