Advertise with Googlier.com Amaury Graillat - Coding http://amoweb.fr/categorie18/coding fr amoweb.fr Wed, 01 Nov 2023 15:46:00 +0100 PluXml Créer une librairie (DLL) en C ou C++ : quelques erreurs à éviter http://amoweb.fr/article208/creer-une-librairie-dll-en-c-ou-c-quelques-erreurs-a-eviter http://amoweb.fr/article208/creer-une-librairie-dll-en-c-ou-c-quelques-erreurs-a-eviter <p>In english: <a href="https://amoweb.fr/article209/how-to-create-a-c-or-c-library-dll-common-mistakes">How to create a C or C++ library (DLL) : common mistakes</a>.</p> <p>Il est fréquent de fournir une librairie (bibliothèque) pour permettre au client d'utiliser votre produit dans son logiciel. Par exemple, si vous fournissez un logiciel de calcul scientifique, le client aura peut-être besoin de lire les fichiers générés par votre logiciel ou bien intégrer certains calculs à son produit. Si vous vendez des sondes de dioxyde de carbone, vous fournissez sûrement une DLL (Dynamic Link Library) permettant de lire les mesures. </p> <p>Peu importe dans quel langage est développé votre logiciel, fournir une interface en C est permet une intégration presque partout et une utilisation dans la plupart des langages. </p> <p>Sous Windows, vous fournissez donc un fichier .dll contenant les fonctions utiles au client, un fichier .lib qui liste ces fonctions et indique comment les trouver dans la .dll et un fichier .h qui contient la signature des fonctions lisibles par le programmeur. Sous Linux, la DLL s'appelle .so et elle est fournie uniquement avec un fichier .h.</p> <h2>Faut-il fournir une interface en C ou en C++ ?</h2> <p> Si vous avez développé votre programme en C++ et que vos clients utilisent du C++, fournir une DLL pour ce même langage permet d'en simplifier l'utilisation pour le client car il bénéficiera des avantages des classes, des références, etc. C'est ce que fait <a href="https://www.qt.io/">Qt</a> par exemple. L'inconvénient est qu'il faut compiler la librairie pour plusieurs compilateurs voire plusieurs versions d'un même compilateur : GCC, Clang, MSVC (Visual Studio 2015, 2022, etc), etc. </p> <p>La librairie standard C++ peut aussi changer entre les versions d'un même compilateur : entre deux versions de Visual Studio, par exemple std::string peut changer et provoquer des plantages difficiles à comprendre.</p> <p>Une librairie C++ a certains avantages, mais a aussi un coût. Une solution est de rendre la bibliothèque open source pour que le client puisse la recompiler ; une autre solution est de développer une interface C++ header-only (uniquement dans le .h) qui cache l'interface C.</p> <h2>Éviter des erreurs fréquentes</h2> <p><b>malloc et free ou bien new et delete doivent être fait dans la même entité (programme ou DLL).</b> Considérez la fonction suivante : </p> <pre>DLL_EXPORT char* GetProjectName(Project_t id);</pre> <p>Ici GetProjectName renvoie une chaine de caractères qui a été allouée par la DLL. Si le compilateur du client est différent du compilateur qui a produit la DLL, désallouer la chaine de caractères avec free peut provoquer un plantage car l'implémentation de l'allocateur peut être différente. Par exemple en debug, malloc et free peuvent être instrumentés pour détecter des problèmes.</p> <p>La solution classique est la suivante :</p> <pre> DLL_EXPORT void GetProjectName(Project_t id, char* name); </pre> <p>Dans ce cas le client doit allouer un tableau et GetProjectName va copier la chaine. Il faut fournir au client la taille maximum possible ou une fonction GetProjectNameLength. Un alternative est de définir un type qui contient la chaine :</p> <pre> typedef struct MyString_ { const char * const str; } MyString_t; </pre> <p>Et des fonctions pour manipuler MyString_t :</p> <pre> DLL_EXPORT MyString_t* CreateMyString(const str* ms); DLL_EXPORT void DeleteMyString(MyString_t* ms); DLL_EXPORT MyString_t* GetProjectName(Project_t id); </pre> <p>Les fonctions CreateMyString et GetProjectName font un malloc et la fonction DeleteMyString, un free. C'est donc la DLL qui se charge à la fois de l'allocation et de la libération de la mémoire.</p> <p> On réduit aussi les erreurs car l'utilisateur n'a plus besoin de se soucier d'allouer la bonne taille. Les consts interdisent la modification de str par l'utilisateur pour éviter que DeleteMyString se retrouve à appeler free sur des données allouées par l'utilisateur. </p> <p> <b>Clarifier l'interface.</b> Et les types sont là pour ça. On considère la fonction suivante : </p> <pre>DLL_EXPORT int GetCurrentProjectId(); DLL_EXPORT void RemoveFile(int projectId, int fileId);</pre> <p>Ici ce code peut être rendu beaucoup plus clair avec des types</p> <pre> typedef int ProjectId_t; typedef int FileId_t; DLL_EXPORT ProjectId_t GetCurrentProjectId(); DLL_EXPORT void RemoveFile(ProjectId_t projectId, FileId_t fileId); </pre> <p>Malheureusement, le compilateur n'émettra même pas un warning si l'utilisateur place un ProjectId_t au lieu d'un FileId_t, mais le code est quand même plus lisible.</p> <p><b>Const correctness.</b> Déclarer les pointeurs ou références const dès que possible.</p> <pre>DLL_EXPORT char* SetProjectName(Project_t id, const char* str);</pre> <p>Ici, str est const char*, c'est indispensable si l'utilisateur veut passer une chaine de caractère constante. Son code ne pourra pas respecter la const correctness si vous ne le faites pas.</p> <p><b>Pas plus de 4 paramètres pour vos fonctions.</b> Utiliser une structure si la fonction a trop d'entrées. Pour retourner plusieurs paramètres utilisez des structures. N'utilisez surtout pas de tableaux pour renvoyer des données de natures différentes. Par exemple renvoyer un tableau contenant [x y z] peut être dangereux car l'utilisateur risque de se tromper d'ordre. En C++, évitez les std::pair qui ont ce défaut aussi.</p> <p><b>Utilisez des <a href="https://en.wikipedia.org/wiki/Opaque_pointer">pointeurs opaques</a> pour identifier les instances de votre lib</b>, cela permet de cacher les données stockées. En C++, le patron <a href="https://en.cppreference.com/w/cpp/language/pimpl">PIMPL</a> sert à ça. Dans les exemples précédents, j'ai utilisé des entiers (par exemple Project_t) ce qui est moins efficace car il faut une map qui stocke la correspondance mais c'est parfois plus facile à gérer dans le logiciel du client.</p> <p> <b>Bien documenter le format des données, les types et les unités</b> GetPressure, GetTemperature, GetDistance ne veulent rien dire si on ne précise pas si ce sont des bars, des N/m², des °C, °F, des mètres ou des mm. </p> <p><b>Le plus important : la lib est l'interface entre vous et le client.</b> La documentation et le nom des fonctions doit utiliser les termes du client pas un jargon interne !</p> <p>En conclusion, demandez-vous ce que le client va comprendre de votre interface et quelles erreurs il va faire. Facilitez-lui la tâche en rendant les erreurs difficiles voire impossibles.</p> Wed, 01 Nov 2023 15:46:00 +0100 Amaury Graillat Thermostat intelligent (ESP32) http://amoweb.fr/article204/thermostat-intelligent-esp32 http://amoweb.fr/article204/thermostat-intelligent-esp32 <p>Les thermostats classiques permettent de programmer des plages horaires pendant lesquelles le chauffage est en route. Par exemple, on peut définir un démarrage à 6h pour que la pièce soit chaud à 7h. Malheureusement, en fonction de la température extérieure, parfois il fera chaud à 6h30, et parfois il fera chaud à 7h30.</p> <p>Ce thermostat permet d'adapter l'heure de démarrage en fonction de la vitesse de chauffe. On définit ainsi des horaires de présence au lieux de définir des horaires de chauffe.</p> <p><img src="/pluxml/data/images/thermostat_connecte_1.jpg" alt="Courbe de chauffe chaudière." width="600px" /><br /></p> <p>Par exemple, si la vitesse de chauffe est de 2°C par heure et qu'il fait 18°C. Il suffira de chauffer à 6h30 pour qu'il fasse 19°C à 7h. J'appelle cette vitesse pente, elle est exprimée en °C / h et est mise à jour à chaque chauffe.</p> <h3>Matériel</h3> <p>Je n'ai pas fait grand chose de ce côté là. Vincent m'a prêté le matériel et a fait quelques soudures. Et pour l'instant, j'ai tout monté sur une platine de prototypage.</p> <ul> <li>ESP32-PICO-KIT V4</li> <li>Sonde de température TMP175 (I2C)</li> <li>Un relais de type SRD-05VDC-SL-C</li> <li>LEDs, boutons poussoirs, etc</li> </ul> <h3>La base : les entrées/sorties<h3> <p>Tout est programmée en C avec la toolchain IDF de l'ESP32. J'ai essayé les différents éléments tout seul : une première sonde de température analogique, puis la sonde I2C, puis le relay, etc. Je me suis aussi familiarisé avec le wifi sur ESP32 et le serveur web.</p> <h3>Fonctionnement du régulateur</h3> <p>La chaudière est pilotée en tout ou rien. Lorsque le relais est passant, la chaudière chauffe, sinon elle s'arrête.</p> <p>Ce thermostat implémente une hystérésis. C'est-à-dire que pour atteindre une consigne à 19°C, il va chauffer jusqu'à dépasser un peu la température (19.3°C par exemple). A la descente, il va attendre de dépasser la consigne (18.7°C par exemple) pour chauffer. </p> <h3>Fonctionnement de la prédiction</h3> <p>La prédiction à deux entrées : le booléen qui indique la chauffe et la température. Grâce à ces deux données, elle actualise la pente (en °C/h). </p> <p>La prédiction agit au début et à la fin de la chauffe. C'est-à-dire lorsque <i>chauffe</i> passe à vrai, puis lorsqu'il passe à faux. Elle enregistre alors 2 points X1 et X2. Si la différence de température entre ces deux points est d'au moins 1 degré, elle calcule la pente. La pente est la différence des températures entre X1 et X2 divisée par la durée entre X1 et X2.</p> <p>Pendant un période d'absence, le logiciel calcule le temps qu'il faudra pour atteindre la consigne. Cette durée dépend de la température actuelle et de la pente. Lorsque la durée jusqu'à la période de présence est inférieure à ce temps de chauffe, la consigne du régulateur est mise à jour pour atteindre la température de présence. </p> <h3>L'Architecture</h3> <p><img src="/pluxml/data/images/thermostat_connecte_2.jpg" alt="Modules du thermostat qui adapte le temps de chauffe." width="600px" /><br /></p> <p>Le module Régulateur (<a href="https://github.com/amoweb/ThermostatConnecte/blob/main/ESP32/main/controller/hysteresis/hysteresis.h">controller/hysteresis.h</a>) implémente l'hystérésis. Il pend en entrée la température actuelle et renvoie le booléen chauffe. Il est paramétré par une consigne.</p> <p>Le module Prédiction (<a href="https://github.com/amoweb/ThermostatConnecte/blob/main/ESP32/main/controller/estimator/estimator.h">controller/estimator.h</a>) reçoit en entrée la température actuelle et le temps (jour de la semaine, heure et minute) et renvoie la pente.</p> <p>Enfin le module Gestion (le main dans <a href="https://github.com/amoweb/ThermostatConnecte/blob/main/ESP32/main/thermostat.c">thermostat.c</a>) reçoit la température actuelle et définie la consigne en fonction de la pente et des horaires de présence.</p> <p>Tout ces modules reposent sur une couche d'abstraction donnant accès au matériel (température, relais, bouton poussoir) et au serveur web (définition des endpoints). Un module stock aussi la configuration et les horaires sous forme d'un jour (lundi-dimanche), heure et minute.</p> <h3>Interface web</h3> <p><img src="/pluxml/data/images/thermostat_connecte_3.png" alt="Page web du thermostat connecté." width="600px" /><br /></p> <p>Tout est très léger et sans cosmétique. Un endpoint permet d'accéder aux statistiques sur 24h (température, pente et chauffe).</p> <p>Deux boutons poussoirs permettent de passer en mode présence ou absence.</p> <h3>Améliorations</h3> <p><ul> <li>Ajouter un écran LCD. Il pourrait même permettre de remplacer l'interface web.</li> <li>Économie d'énergie : mettre l'ESP32 en veille entre chaque mesure.</li> </ul></p> Sun, 23 Oct 2022 21:52:00 +0200 Amaury Graillat Raspberry Pi : une chaine hifi radio Internet http://amoweb.fr/article164/raspberry-pi-une-chaine-hifi-radio-internet http://amoweb.fr/article164/raspberry-pi-une-chaine-hifi-radio-internet <p> Mini projet d'une demi-journée (ou plutôt 2h) : permettre d'écouter des radios Internet depuis le Raspberry Pi sans écran. J'ai utilisé une souris comme IHM. Le principe est simple : le programme lance <em>cvlc</em> avec un flux, l'appui sur un bouton de la souris change le flux. Le nom de la radio est annoncé avant la lecture. </p> <pre> #!/bin/bash next() { /home/pi/RadioPi/mouse while killall vlc; do echo "kill"; done } while true; do echo "Jazz radio" | espeak sudo -u pi cvlc http://radio/flux.mp3& next echo "BBC Radio 1" | espeak sudo -u pi cvlc http://radio/flux.asx& next done </pre> <p>La fonctionnement n'est pas très propre car <em>cvlc</em> ne nous offre pas de possibilité de le fermer autrement que par un kill. Le programme mouse rend la main dès qu'un bouton de la souris est appuyé.</p> <p> Le programme est appelé dans <em>rc.local</em> par : </p> <pre> sudo -u pi /home/pi/RadioPi/radios.sh& </pre> <p> On note le <em>sudo -u pi</em> qui permet de lancer le script par l'utilisateur pi, car VLC ne peut pas être exécuté par le root. </p> <p> Code source de mouse : </p><pre> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <stdbool.h> #include "ihm.h" #include <stdio.h> #include <unistd.h> #include "ihm.h" int fdMouse; char b[3]; void IHMinit() { fdMouse = open("/dev/input/mice", "r"); fcntl(fdMouse, F_SETFL, O_NONBLOCK); } // Renvoie 1 lors d'un événement souris char IHMuserEntry() { int r = read(fdMouse, b, 2); if(r == 2) { return 1; } return 0; } int main() { IHMinit(); while(1) { char r = IHMuserEntry(); usleep(200); if(r) { return r; } } } </pre> Thu, 02 Jan 2014 19:04:00 +0100 Amaury Graillat Mes conseils de programmation http://amoweb.fr/article162/mes-conseils-de-programmation http://amoweb.fr/article162/mes-conseils-de-programmation <p> Je vais essayer de décrire dans ce documents quelques principes de base que j'applique en programmant. Pour trouver l'essentiel, il m'a fallu prendre du recul sur mes habitudes. </p> <h2>Le nom doit permettre de comprendre ce que fais la fonction ou la variable</h2> <p> Pour les fonctions, l'habitude et de mettre un verbe d'action dans le nom. Pour les plus courants on trouve :<br /> <strong>récupère (get)</strong> : elle renvoie quelque chose (il n'y a aucune raison que dans son code elle modifie une quelconque variable !! sinon, lui trouver un autre nom)<br /> <strong>modifie/ajoute/supprime (set/add/del)</strong> : modifie une valeur/une liste ou un tableau<br /> On peut l'étendre à n'importe quel verbe d'action : <strong>tri</strong>, <strong>analyse<strong>, <strong>nettoie<strong>... </p> <p> Si la fonction est dans un package, il peut parfois être pratique (en C, par exemple), de donner le nom du package aux fonctions. Par exemple : donnéesInit, donnéesReset, donnéesAjout...<br /> <br /> <strong>Important : si on modifie le contenue d'une fonction, il faut penser aussi à mettre à jours son nom si son but change, ou au moins sa documentation.</strong> </p> <p>Pour les tableau, utiliser le terme "tab" dans le nom est souvent assez pratique.</p> <h2>Documenter ses fonctions (toutes)</h2> <p>Description de la fonction<br /> <strong>Paramètres</strong> : liste des paramètres avec l'utilité. Indiqué s'il sont modifiés.<br /> <strong>Retour</strong> : ce qui est retourné. </p> <p> Sur les fonctions ou procédures complexes, on peut ajouter les champs suivants : <strong>Requis</strong> : ce qui doit être fait avant l'appel. Par exemple : appel à "init" requis.<br /> <strong>Garantie</strong> : ce que l'on assure après (par exemple, "le tableau T est trié ou vide")<br /> <br /> Dans le cas où le champ requis a été utilisé, il est peut-être intéressant de placer une assertion en début de fonction, pour assurer que cela a été fait. </p> <h2>Être capable de dessiner sa structure de données</h2> <p> Prendre une feuille de papier et dessiner ses tableaux, ses listes chainées... Ce conseil est sans doute le plus "scolaire" que je puisse donner, mais il vous propulse instantanément au rang de <em>serial coder</em>, surtout dans les langages comme le C où les pointeurs rendent le code peu lisibles. </p> <p style="text-align:center"><img src="http://amoweb.fr/pluxml/data/images/coding/structurededonnees.png" alt="Apprendre à dessiner une structure de donnée" /><br /> Il n'y a plus qu'à faire la correspondance. En C, le tableau deviendra [], les pointeurs, dessinés par des flèches, deviendront des étoiles...</p> <h2>Classer ses fonctions par package (même en C, avec les .h)</h2> <p>Permet de leur donner une logique globale. Cela facilite aussi la factorisation du code. Être capable de classer ses fonctions traduit le fait que l'on comprend l'architecture de son programme. Dans le meilleur des cas, il faut décrire quel seront les packages avant même de commencer à coder. Il est intéressant aussi de décrire les interactions entres les différents packages.<br /> Nb. Pour la programmation objet (Java, C++), c'est encore plus vrai.</p> <h2>Éviter les effets de bords (modification de variables)</h2> <p>Il faut éviter de modifier des variables du programme depuis une fonction (mais c'est parfois indispensable ou juste plus lisible). Dans ce cas, on doit comprendre ce qui est modifié juste en lisant la documentation de la fonction et son nom.<br /> Exemple (trivial), en lisant la documentation de la fonction int get_numéro(), on ne s'attends pas à ce qu'elle modifie une variable. On s’attend juste à ce qu'elle renvoie le numéro.</p> <p>Pour les procédures c'est moins vrai : "l'effet de bord" est leur seul moyen d’interagir avec l'extérieur. Cependant, si elles modifient plusieurs variables, il faut se demander si le développeur s'y attend, juste en lisant la doc.</p> <h2>Appeler ses fonctions avant de les écrire</h2> <p>Cela permet de s'assurer qu'elle est utile avant de l'appeler et d'évaluer quels seront les paramètres. Parfois, j'aime même effectuer les appels de toutes mes fonctions, et les écrire ensuite. Ça peut être inutile, si vous savez exactement quoi coder.</p> <p>En conclusion, nous voyons que la programmation nécessite une certaine rigueur : savoir à tout instant POURQUOI j'écris cette ligne. <strong>Le code est à destinations de machines, mais il doit surtout être lisible par des humains, c'est pourquoi il est important de le rendre compréhensible.</strong></p> Thu, 21 Nov 2013 21:39:00 +0100 Amaury Graillat Du code, et encore du code http://amoweb.fr/article153/du-code-et-encore-du-code http://amoweb.fr/article153/du-code-et-encore-du-code <p> Si vous n'avez pas encore jeté un œil à la section <a href="http://amoweb.fr/static4/softs">Réalisations</a> sachez que j'ai ajouté pas mal de réalisation durant cette année. </p> <p> <ul> <li><a href="http://forum.pluxml.org/viewtopic.php?id=3344">plxPermalinks</a> : Un plugin PluXml permettant de configurer vos url à volonté.<br/></li> <li>Monôme2Monôme : une messagerie instantanée très simple en java (résultat d'un projet) (GNU GPL)<br /></li> <li>amowebCartographie : un logiciel de cartographie de valeurs compatible Google Earth (GNU GPL)<br /></li> <li>amowebMathParser : un parser d'expressions mathématiques en java (LGPL)</li> </ul> </p> <p>C'est disponible sur <a href="http://amoweb.fr/static4/softs">cette page</a>.</p> Wed, 11 Jul 2012 11:44:00 +0200 Amaury Graillat Bash : Remplacer les caractères d'échappement HTML en caractères UTF-8 http://amoweb.fr/article147/bash-remplacer-les-caracteres-d-echappement-html-en-caracteres-utf-8 http://amoweb.fr/article147/bash-remplacer-les-caracteres-d-echappement-html-en-caracteres-utf-8 <p> Voici un petit script bash permettant de remplacer, dans tous les fichiers d'un répertoire, les séquences d'échappement HTML par le caractère qu'elle représentent (UTF-8).<br/> J'ai pris la liste des caractères d'échappement de <a href="http://www.theukwebdesigncompany.com/articles/entity-escape-characters.php">theukwebdesigncompany.com</a>. </p> <p> Avant de l'exécuter, comprenez comment il fonctionne et sauvegardez vos fichiers, ça vous évitera de perdes des documents.<br /> <a href="http://amoweb.fr/pluxml/data/documents/bash/convhtml-utf8.sh.zip">convhtml-utf8.sh.zip</a> </p> Wed, 21 Dec 2011 18:44:00 +0100 Amaury Graillat Une machine à boucle midi http://amoweb.fr/article141/une-machine-a-boucle-midi http://amoweb.fr/article141/une-machine-a-boucle-midi <p> Comme me l'a fait judicieusement remarqué <a href="http://amoweb.fr/article133/edito-du-27-mai-2011-des-cours-et-des-mises-a-jour#c1312095384-1">Pascal</a>, je vous avais parlé dans mon <a href="http://amoweb.fr/article133/edito-du-27-mai-2011-des-cours-et-des-mises-a-jour">dernier édito</a> de la conception d'un logiciel permettant de faire des boucles avec un instrument midi. </p> <p> <em>Attention ! Par manque de temps, j'ai développé ce logiciel sous Windows et je n'ai pas testé son fonctionnement sous Wine.</em> </p> <p> Les principe est simple, il y a une touche pour lancer l'enregistrement et pour l'arrêter et faire boucler les notes (le C# de l'octave 6, cela est modifiable dans les premières lignes du programme). </p> <h2>Petite explication sur la norme midi :</h2> <p> Il s'agit d'une norme très simple inventée dans les débuts de l'informatique musical.<br /> Ce sont des messages de 4 octets, comportant le numéro de l'appareil cible (un numéro de canal) suivit d'une instruction. Par exemple, jouer une note, l'arrêter...<br /> Cette norme n'a donc aucun connaissance musicale. Les messages envoyés donnent des information sur le début et la fin des notes, mais pas sur la durée. Ce logiciel doit donc chronométrer le temps entre le début et la fin des notes. </p> <p> Pour simplifier la conception, je mémorise donc dans un tableau, à chaque évènement, le message envoyé, s'il s'agit d'une nouvelle note, ou s'il s'agit d'un relâchement, avec le temps écoulé depuis la dernière opération. Ensuite, le logiciel a juste besoin de relire la liste, en attendant le temps nécessaire. </p> <p> Le code source et une version compilée pour Windows x86 est téléchargeable <a href="http://amoweb.fr/pluxml/data/documents/boucle.zip">ici</a>. </p> Sun, 31 Jul 2011 11:25:00 +0200 Amaury Graillat Le RapidQ n'est pas mort ! L'exemple d'une carrière en informatique. http://amoweb.fr/article134/le-rapidq-n-est-pas-mort-l-exemple-d-une-carriere-en-informatique http://amoweb.fr/article134/le-rapidq-n-est-pas-mort-l-exemple-d-une-carriere-en-informatique <p><span style="margin-left: 5em;"/>Je suis retourné hier sur le forum <a href="http://rapidq-france.org">rapidq-france.org</a>. C'était l'époque où j'ai commencé la programmation, en 2005. Je ne connaissais n'avais pas de méthode ce qui limitait la taille des projets, mais je cherchais, et me débrouillais. RapidQ me permettait de développer très rapidement des applications fenêtrées. Il y a des milliers d'exemples sur Internet : des jeux on 3D utilisant directx on été développés avec ce langage. La communauté a été très importante. Car il fonctionne sans DLL, ce qui le rend beaucoup plus simple à diffuser que le VisualBasic, qui fonctionne avec un tas de bibliothèques dont on ne possède jamais la bonne version...</p> <p style="text-align:center"> <img src="http://amoweb.fr/pluxml/data/images/geek/rapidq.jpg" alt="RapidQ IDE" /> </p> <p><span style="margin-left: 5em;"/>RapidQ est né un peu avant 2000. Créé par William Yu, il a su conquérir beaucoup de monde par sa simplicité. Mais voilà qu'un jour son créateur a annoncé la fin du développement. RapidQ est gratuit, mais en aucun cas libre. William Yu a déjà publié un compilateur sous licence GNU, mais il a refusé de le faire pour RapidQ.</p> <p><span style="margin-left: 5em;"/>Quelques semaines plus tard, William Yu a publié une <a href="/pluxml/data/documents/williamyu.html">lettre</a> sur sa <a href="http://tech.groups.yahoo.com/group/rapidq">liste de diffusion</a>, où il expliquait son choix. William était confronté à un dilemme : vendre son travail à RealBASIC et se faire embaucher, ou continuer à distribuer RapidQ : <i>"The facts are, I could have made more money working at McDonalds than the time spent on Rapid-Q and what Geoff has offered me to stop working on it"</i>, déclarait-il dans sa lettre d'Octobre 2000.<br/> Il s'en est suivit une discussion assez mouvementée sur la liste. Certain en ont voulu à Geoff, le directeur général de RealBASIC, car il était très présent sur la liste de diffusion pour parler de sa société. Cela a été vu comme de la publicité gratuite. Certain on dit aussi que Geoff avait tout intérêt à faire disparaitre le langage, et son développeur avec. Lorsque l'on compare ces deux langages, ils se ressemblent en tout point. Il est même possible de créer des fenêtres avec l'éditeur de RapidQ et de compiler le code sans aucune modification sous RealBASIC (Real Studio).</p> <p><span style="margin-left: 5em;"/>C'était il y a 11 ans, la liberté de diffusion n'était pas encore un argument commercial pour les entreprises, et elle n'avait pas encore cette puissance chez les développeurs. Les amateurs de RapidQ diront que son rachat est une catastrophe car ils pensaient que RapidQ allait devenir un très grand langage. Mais avec un peu de recul, on se rend compte que la version de 2000 n'est pas buggée et qu'elle est toujours compatible avec les dernières version de Windows (et de Linux, puisqu'il existe des versions multiplateforme). Encore une fois, la puissance de ce langage réside dans sa simplicité : il est possible de faire appel très simplement à des DLL, ce qui rend ses possiblités presques infinies.</p> <p><span style="margin-left: 5em;"/>Biensûr, j'aurais aimé qu'il en soit autrement, que le langage soit publié en GNU. Mais l'informatique n'est-elle pas un secteur où l'on peut devenir célèbre ? Où son tallent (car c'est bien de cela qu'il s'agit pour William Yu) peut être reconnu, et permettre de s'élever socialement ?<br /> Finalement, William Yu a gagné le respect de milliers de développeurs, et a trouvé un emploi dans une société implantée dans 7 pays. Une belle carrière dans l'informatique, non ?</p> Fri, 03 Jun 2011 11:15:00 +0200 Amaury Graillat