On ne fait pas de la magie

«Toute technologie suffisamment avancée est indiscernable de la magie.» Arthur C. Clarke

Étiquette : Formation

  • Le piège des analogies entre les langages

    Lors des formations que j’anime, j’essaie d’utiliser les connaissances et les habitudes des apprenants pour leur faire comprendre les nouveaux concepts. Par exemple, je peux utiliser du code qu’ils lisent aisément en C ou C++, issu d’une formation C++, pour leur montrer comment l’écrire en Fortran.

    Il est important de bien expliquer les différences entre les langages lorsqu’on utilise cette approche.

    (suite…)
  • Fonctions lambda récursives en C++23 avec le deducing this

    Fonctions lambda récursives en C++23 avec le deducing this

    Comme à chaque fois que je prépare une nouvelle session de formation C++ 20 et 23, j’ai refait le tour des exemples que je présente. L’un d’eux concerne une des utilisations possibles du « deducing this », qu’il me parait intéressant de vous présenter.

    (suite…)
  • MSI et Windows Installer

    A l’occasion d’une formation Installshield, j’ai rafraichi ma liste d’outils tournant autour de MSI et de Windows Installer.

    Voilà un extrait de la panoplie :

    MAKEMSI est un logiciel freeware qui permet de construire un package MSI à partir d’une description définie dans un fichier XML.

    Dans la même lignée, j’aurais tendance à préférer WiX (Windows Installer Toolkit) qui utilise lui aussi une syntaxe XML pour décrire une installation. Il dispose d’un sous projet Votive pour manipuler ses fichiers avec Visual Studio.

    Advance Installer est un outil de conception d’installation, avec une interface graphique, disponible sous plusieurs éditions. Il existe une édition gratuite qui permet de créer des projets simples.

    Enfin, si Orca vous semble trop rudimentaire ou rébarbatif, vous pouvez utiliser InstEd pour éditer directement vos fichiers MSI.

  • Erreur 80243004 lors d’un update Windows

    Erreur 80243004 lors d’un update Windows

    Lors de la préparation d’une formation Windows Server, je suis tombé sur un problème dont la cause m’a fait sourire.Erreur 80243004 lors d'un update Windows

    En appliquant les mises à jour sur une machine virtuelle Windows Server, j’obtiens une erreur 80243004 et tout l’update échoue.

    Un peu de recherche dans la base de connaissance Microsoft me donne la solution  (https://support.microsoft.com/kb/2837515) : il faut que l’icône de notification de Windows Update soit activée dans la zone de notification pour que les mises à jour puissent se faire !

    Je crois que c’est le bug le plus amusant que j’ai vu depuis quelques mois …

    PS : Petit truc pour résoudre plus rapidement vos problèmes : N’utilisez pas une recherche large sur Google pour ce genre de difficultés. Vous avez un problème clairement identifié, chez un éditeur, avec un numéro ? Aller directement chercher dans les informations mises à disposition par cet éditeur vous fera gagner beaucoup de temps en n’ayant pas à lire de nombreux messages décrivant le même problème, sans fournir de solutions, ou – pire – donnant des solutions douteuses.

  • Surcharger l’opérateur new pour empêcher l’allocation dynamique d’un objet en C++

    Parfois, il est nécessaire de restreindre des objets pour qu’ils ne puissent être utilisés qu’au travers de variables locales. Un cas typique est une classe qui utilise des ressources, allouées logiquement dans son constructeur, et libérées dans son destructeur.

    Voici un exemple que j’utilise parfois dans les formations au C++.

    Tout va bien si le programme détruit les objets lorsqu’ils n’en a plus besoin.
    C’est le cas si on emploie ces objets à l’aide de variables locales : lorsque le programme quitte la portée dans laquelle la variable existe (nous présumons bien sûr que la variable n’est pas statique), l’objet est détruit, et le passage dans le destructeur libère les ressources allouées dans le constructeur.

    Le risque est qu’un développeur crée un objet en utilisant une allocation dynamique, car il pourrait ensuite oublier de détruire cet objet, bloquant ainsi les ressources.

    Une solution pour supprimer ce risque consiste tout simplement à surcharger l’opérateur new de notre classe, de façon à empêcher l’allocation dynamique d’objets de cette classe. Voici un petit exemple qui montre le principe :

    class maClasse {
    public:
          string chaine;
          maClasse() {
    // allocation des ressources
         chaine = "Les ressources sont allouees";
    };
    ~maClasse() {
    // libération des ressources
          cout << "Les ressources sont liberees" << endl;
    }
    void *operator new (size_t taille) {
    throw 0;
    return new int; // peut renvoyer n'importe quoi : on ne passera jamais ici
    }
    };
    int main(int argc, char* argv[]) {
    { 
    // bloc pour montrer la réservation et la libération des ressources
           maClasse C1;
          cout << C1.chaine << endl;
    }
    try {
          maClasse * pC = new maClasse;
          cout << pC->chaine << endl;
    }
    catch (int e) {
          cout << "Exception : " << e << endl;
    }
    int attente;
    cin >> attente;
    return 0;
    }

    La sortie nous montre que nous avons bien utilisé la variable locale, en allouant, puis en libérant les ressources, mais que l’utilisation d’une allocation dynamique échoue :

    $ ./essai
    Les ressources sont allouees
    Les ressources sont liberees
    Exception : 0

     

  • Comment utiliser Installshield pour effacer des fichiers lors d’une installation ?

    Une question récurrente qui m’est posée lors d’interventions sur Installshield concerne la suppression de fichiers présents sur la machine cible au moment de l’installation.

    Il est normal qu’elle soit posée, car la réponse n’apparaît pas de façon évidente dans l’interface du logiciel.

    Si vous souhaitez supprimer des fichiers qui sont présents lors de l’installation, il faut renseigner la table RemoveFile, en vérifiant l’action RemoveFiles est bien présente dans la séquence d’installation.

    Cette table contient contient une propriété DirProperty qui indique le chemin complet du répertoire du fichier à supprimer. InstallMode permet de spécifier si le fichier est effacé lors de l’installation, de la désinstallation ou dans les deux cas.

    EffacerFichierInstallshield1.png

    Le composant indiqué doit bien sur être associé à une fonctionnalité installée pour que l’opération soit exécutée.

    Attention, l »interface graphique d’Installshield ne montre pas la liaison entre le composant et la table RemoveFile. Notamment, si on demande à n’afficher que les nœuds non vide, le composant peut apparaitre comme vide alors que la table RemoveFile fait référence au composant.

    EffacerFichierInstallshield2.png

    Vous pouvez constater que le composant EffaceFichier semble vide alors qu’il est utilisé pour supprimer des fichiers au travers de la table RemoveFile :

    EffacerFichierInstallshield3.png

     

    .

  • Comment utiliser Installshield pour forcer l’installation de fichiers par Windows Installer ?

    Lors des prestations ou de formations sur Windows Installer ou Installshield, j’ai parfois la question de forcer l’installation de fichiers sans tenir compte des caractéristiques de taille ou de version de ceux qui seraient éventuellement déjà présents.

    C’est une possibilité que vous pouvez indiquer dans la fenêtre de propriété d’un fichier, en cochant l’option Always Overwrite.

    EcrasementFichierInstallshield.png

    Que fait Installshield lorsque cette option est cochée ? Il inscrit tout simplement la valeur 65535 dans la colonne Version de la table File. De cette façon, les mécanismes normaux de Windows Installer forcent l’installation du fichier, quelle que soit la version du fichier éventuellement installée sur le système.

    La difficulté de cette méthode est qu’il faut passer en revue tous les fichiers de tous les composants et cela peut devenir une tâche rédhibitoire s’ils sont nombreux.

    Pour éviter cela, à partir de Windows Installer 4, il est possible d’utiliser la propriété REINSTALLMODE ou l’option /f de la ligne de commande de msiexec.

    Cette option est normalement utilisée en combinaison avec la propriété REINSTALL, mais Windows Installer la prend aussi en compte lors d’une installation. En spécifiant la valeur a, tous les fichiers sont copiés, indépendamment des versions. Vous pouvez tout simplement l’indiquer sur la ligne de commande ou l’incorporer à votre installation en utilisant le Property Manager ou encore en modifiant la table Property avec le Direct Editor.

    Attention, il peut y avoir des effets de bords. Par exemple, si votre installation contient des modifications du registre, celles ci ne sont pas effectuées si REINSTALLMODE ne contient que la valeur a. Il faut ajouter les valeurs u ou m pour que le registre soit modifié !

  • Le SEO, ce n’est pas de la magie !

    Comment résister, dans le blog « On ne fait pas de la magie », à l’envie de citer un article luttant contre la magie ?

    Je vous invite à consulter l’article : Le web social ce n’est pas magique, dans lequel vous trouverez de bonnes pratiques pour utiliser au mieux les réseaux sociaux.

    Nous présentons certaines de ces bonnes pratiques dans les formations Webmarketing que nous proposons, et notamment dans les ateliers Utiliser Facebook pour communiquer sur son activité professionnelle.

  • La magie du C++

    Non vous ne rêvez pas, j’ai bien utilisé le mot magie dans le titre d’un article sur le blog On ne fait pas de la magie ! Mais vous vous doutez bien qu’il y a anguille sous roche et qu’on va faire de l’anti-magie.

    L’une des opinions courantes sur le C++ est que c’est un langage difficile à employer, car il est facile de commettre des erreurs de programmation qui se traduisent par des fuites mémoires ou l’accès à des objets qui n’existent plus. En contrepartie, il est souvent également admis que le code C++ est plus rapide à l’exécution que du code Java ou C#, pour lesquels les fuites mémoires n’existent pas.

    Quelles sont les raisons sous-jacentes de ces opinions ? La principale est que le développeur C++ doit gérer lui même la durée de vie des objets qu’il utilise. Cela se traduit souvent par la contrainte d’avoir à écrire un constructeur copie ou à surcharger l’opérateur d’affectation d’une classe. Mais cela lui offre la souplesse de maitriser l’instant exact où une ressource est libérée, qu’elle soit une ressource mémoire ou une connexion à une base de données.

    Notamment, cela permet d’écrire une application en utilisant le principe RAII (Resource Acquisition Is Initialisation) sans avoir à veiller à chaque utilisation de sa classe à l’encapsuler avec une instruction using ou à ne pas oublier une clause finally d’un bloc try. C++ ne dispose pas de using ni de finally parce qu’il n’en a tout simplement pas besoin …

    De ce fait, le développeur a moins d’instructions à écrire et l’application moins de code à exécuter : il n’y a pas de besoin de code supplémentaire exécuté dans un thread séparé pour faire le ménage dans les objets à détruire. Cerise sur le gâteau, les performances d’une application C++ sont déterministes, alors qu’une application Java ou C# peut présenter des ralentissements aléatoires déclenchées par le passage du garbage collector.

    Ces opinions risquent de se renforcer à juste titre avec l’utilisation judicieuse des nouvelles fonctionnalités du C++ 11, maintenant largement adopté par les principaux compilateurs actuels. En effet, les nouveaux types de smart pointers, comme unique_ptr ou shared_ptr, ou la notion de RValues, qui permet d’écrire un constructeur move vont continuer à faciliter l’écriture d’application plus efficaces, en réduisant le nombre de lignes de code source écrites par le développeur, ainsi que le nombre d’instructions machine exécutées.

    Le constructeur move est particulièrement efficace de ce point de vue, en évitant la création d’objets temporaires qui peuvent nécessiter des tailles mémoire importantes et des temps d’initialisation conséquents.

    Pour obtenir ces résultats, qui ne sont pas de la magie, mais l’utilisation de mécanismes très bien pensés, le développeur C++ doit consacrer un temps d’apprentissage pour maitriser ces nouvelles notions. C’est le message que, pour ma part, je fais passer dans les formations C++, notamment la formation aux nouveautés C++ 11, que j’anime.

  • HTML et CSS pour les CMS

    Publier un site Web pour présenter son activité, écrire un blog, … est aujourd’hui très aisé grâce aux CMS (WordPress, Joomla, …) ou aux outils de publication en ligne (Weebly, 1and1, Facebook, …).

    Ces solutions proposent de nombreuses mises en forme prédéfinies, des templates, des pluggins qui permettent de personnaliser très finement son site. Mais parfois, il faut modifier du code HTML ou des styles CSS pour obtenir exactement la présentation souhaitée ou pour améliorer le référencement. Et là, on se trouve confronté à des aspects techniques de compréhension de la syntaxe et de l’utilisation du HTML ou du CSS.

    Une formation HTML et CSS classique n’est pas très bien adaptée pour maitriser ces aspects techniques. D’une part, certains sujets n’ont que peu d’intérêt dans le contexte d’un CMS, par exemple les formulaires ou les iframe, et d’autre part, l’accès au HTML et aux styles s’effectue au travers d’éditeurs dédiés.

    Pour ces raisons, j’ai élaboré une formation HMTL/CSS spécifique pour les CMS, mettant l’accent sur la personnalisation de CMS et sur l’amélioration du référencement naturel. La première session aura lieu très bientôt à Grenoble.

  • Ecrire un plugin jQuery pour centrer des éléments

    Lorsqu’on utilise jQuery, on peut écrire des fonctions javascript classiques qui font simplement appel à jQuery pour effectuer le traitement souhaité.

    L’ennui avec ces fonctions est que leur utilisation est plus délicate que l’utilisation de jQuery.

    Par exemple, prenons le cas d’une fonction qui permet de centrer un élément. Cette fonction peut s’écrire ainsi :

    function centreElement(element) {
    $(element).css({
    'top': (($(window).height() - $(element).height()) / 2) + $(window).scrollTop(),
    'left': (($(window).width() - $(element).width()) / 2) + $(window).scrollLeft()
    });
    }

    Cette fonction peut être appelée sur n’importe quel élément, de cette façon centreElement('#image1'). Mais que se passe t-il si on veut centrer horizontalement plusieurs éléments images ?

    Il suffit de modifier un peu cette fonction pour ne centrer qu’horizontalement. Par contre, il faut exécuter une boucle, par exemple avec la fonction each de jQuery, pour appeler autant de fois que nécessaire cette fonction. Une solution plus élégante peut être d’écrire son propre plugin jQuery, c’est à dire, tout simplement, une fonction personnelle qui se comporte comme une fonction intégrée de jQuery.

    Voilà la façon dont on pourrait écrire un tel plugin :

    (function($) {
    $.fn.centreElement = function() {
    this.each(function() {
    var $e = $(this);
    $e.css({
    'left': (($(window).width() - $e.width()) / 2) + $(window).scrollLeft()
    });
    });
    return this;
    };
    })(jQuery);

    Un plugin jQuery nom est tout simplement une fonction définie avec $.fn.nom. Pour éviter tout télescopage avec d’autres bibliothèques installées, on utilise une fonction anonyme qui reçoit un paramètre $, et on appelle cette fonction avec jQuery :

    (function($) {

    // ici, $ représente jQuery sans aucun risque de télescopage avec une autre bibliothèque

    })(jQuery);

    Il suffit maintenant de définir une fonction anonyme pour $.fn.centreElement.
    Cette fonction doit pouvoir être chainée avec d’autres appels de fonction jQuery et pour cela, elle doit renvoyer l’objet this fourni par jQuery.
    Elle doit également exécuter son traitement sur chaque noeud référencé par jQuery, ce que l’on peut réaliser avec la fonction each().
    Voilà donc la structure que doit avoir tout plugin jQuery :

    $.fn.centreElement = function() {
    this.each(function() { // boucle générique sur chacun de éléments avec la fonction each()
    // code spécifique au plugin écrit
    });
    return this; // valeur de retour pour pouvoir effectuer le chainage
    };

    Et il ne reste plus, pour effectuer le centrage, qu’à reprendre ce que nous avions écrit dans la première fonction, en enlevant le top :

    var $e = $(this);
    $e.css({
    'left': (($(window).width() - $e.width()) / 2) + $(window).scrollLeft()
    });

    Notre plugin permet maintenant d’écrire des instructions comme :

    $('img').centreElement().show();

    Cet exemple est parfois employé comme exercice de cours jQuery