Christophe Jacquet — Carnet — Mot-clé : Programmation

Environnement de développement de drivers sous Windows

J'ai eu besoin de mettre en place un environnement de développement de drivers pour Windows sur mon PC (qui fonctionne sous Windows Vista). Voici la procédure qu'il semble falloir suivre :

  1. Installer Visual Studio 2008.
  2. Installer le WDK (Windows Driver Kit) qui est disponible en version 7. À ce stade, cela ne fonctionne pas encore (messages du type « PASSIVE_LEVEL: undeclared identifier »). En effet, le dernier WDK semble n'être compatible qu'avec la version 7 du SDK de Windows. Or Visual Studio 2008 vient avec le SDK en versions 5 et 6...
  3. Installer alors le SDK Windows version 7 (attention, il fait 4 Go...).
  4. En l'état, cela ne fonctionne pas encore, il reste à sélectionner ce SDK, sinon Visual Studio continue à utiliser l'ancien. Procédure : lancer un shell avec l'environnement adapté au SDK (Démarrer > Tous les programmes > Windows SDK v7 > CMD Shell), puis taper la commande WindowsSdkVer.exe -version:v7.0.

Ouf ! Maintenant, cela devrait fonctionner. Encore que, j'ai eu des problèmes avec l'ordre des chemins des includes : il semble que si le DDK apparaît avant le SDK, ça génère des erreurs de compilation dans des fichiers de base. Par exemple, je me suis pris des « "_in_opt_" undeclared identifier » dans new.c ! J'ai résolu le problème en mettant directement le chemin des fichiers .h du DDK dans les directives #include.

Mais au fait, pourquoi tout ça ? Je poursuis mes expérimentations sur le RDS. J'ai voulu tester la clé USBFMRADIO-RD de chez Silicon Labs. Il s'agit de la réalisation d'une application note de leur chip tuner radio FM avec décodeur RDS, le Si4701. Ce « produit » clé radio étant ouvert (le code source est accessible : firmware et front-end Windows, schémas), je voulais l'utiliser pour récupérer facilement des flux RDS. Le front-end Windows fourni étant vraiment rudimentaire, j'ai dû le modifier et le recompiler pour mes premiers essais. Or il a besoin du DDK pour accéder aux périphériques USB HID...

Restez à l'écoute, je posterai bientôt des nouvelles de mes expérimentations RDS en général, et mon avis sur cette clé lorsque j'aurai poursuivi mes essais !

SQLite et Python

Généralement, quand on évoque une base de données disposant du langage SQL, on pense serveur à mettre en place, comptes utilisateurs à créer, et éventuellement bibliothèques à installer lorsque l'on veut accéder à la base depuis un programme. Bref, une lourdeur certaine, rédhibitoire pour stocker, par exemple, quelques données depuis un script lancé épisodiquement...

Cet article explique comment l'utilisation de bases de données devient simple avec SQLite : pas de serveur à installer, pas gestion des utilisateurs. L'utilisation est aussi simple que celle de fichiers textes. De plus, à partir de Python 2.5, le langage inclut en standard la bibliothèque d'accès aux bases sqlite3. SQLite est notamment utilisé par Firefox 3.

Lire la suite...

Dépendances circulaires dans Eclipse

Aussi étonnant que cela puisse paraître, Eclipse signale par défaut une erreur, et ne compile rien du tout, s'il y a des dépendances circulaires entre projets : il se contente de sortir un message d'erreur du type A cycle was detected in the build path of project.... Les dépendances circulaires sont pourtant nécessaires dans bien des cas.

Pour résoudre le problème, il faut aller modifier une préférence dans Java > Compiler > Building. Là, il faut régler Circular Dependencies sur Warning au lieu de Error.

C# : 1 – Java : 0

À l'occasion de quelques amusements en C# effectués en ce moment...

Il y a deux ans, je m'étais plaint des generics de Java. En effet, le paramétrage des types est effacé à la compilation, ce qui rend certaines opérations impossibles à faire. Par exemple la méthode toArray de l'interface List doit recevoir en paramètre un tableau du type paramètre, car celui-ci est oublié à la compilation. Mais hors de question de pouvoir écrire :

public static <T> T[] truc(T a) {
	List<T> liste = new ArrayList<T>();
	liste.add(a);
	return liste.toArray(new T[] {});
}

L'expression soulignée est incorrecte, parce que justement, à l'exécution la JVM ne connaît pas T... Problème insoluble.

Dans .Net, la CLR n'oublie pas le type des paramètres. Dans une méthode paramétrée par <T>, on peut donc parfaitement écrire une expression du type new T[] { ... }. Et la méthode ToArray n'a donc pas besoin qu'on lui fournisse un tableau du type paramètre. Le code ci-dessus, incorrect en Java, s'écrit de façon élégante en C# :

public static T[] truc<T>(T a)
{
	List<T> liste = new List<T>();
	liste.Add(a);
	return liste.ToArray();
}

Notons que pour ne rien simplifier, les concepteurs de Java et C# ont forcément trouvé le moyen de faire différer la syntaxe au niveau de la place du paramètre <T> dans la déclaration de fonction... Mais clairement, les generics me semblent avoir été traités à la légère en Java. Le système de l'erasure des informations de type, même s'il est suffisant pour assurer la type safety dans la plupart des cas, et même s'il permettait de garder la JVM inchangée, conduit à des solutions vraiment épouvantables (cast + @SuppressWarnings("unchecked")) dans des cas un peu complexes...

Conception d'OS

À partir de 2004, une série d'article très intéressants sur la conception et la réalisation d'un OS est parue dans GNU/Linux Magazine France (GLMF). Le code, les articles de GLMF en PDF, ainsi que divers documents sont disponibles sur le site de cet OS expérimental, appelé SOS.

Graphique de circulation

Soit le problème « ferroviaire » suivant :

Ce billet explique comment y arriver simplement, à l'aide d'un petit script en Ruby et de Gnuplot.

Lire la suite...

Ruby

Je me suis récemment mis à Ruby: je trouve ce langage assez agréable. Il reprend une bonne partie de la concision de Perl, tout en ayant un modèle objet assez propre. Il emprunte également aux langages fonctionnels, ce qui est aussi pratique à l'usage.

Comme petit exercice, j'ai réalisé un programme de résolution de Sudoku. Il n'est pas très intelligent, et procède comme suit :

  • pour chaque case inconnue de la grille, il maintient une liste de possibilités ;
  • il élimine donc les valeurs impossibles par ligne, colonne et bloc ;
  • si au sein d'une ligne, colonne ou bloc une possibilité n'apparaît qu'une seule fois, cela devient une certitude ;
  • si à ce stade la grille n'est pas résolue, on essaie une possibilité et on appelle récursivement la procédure de résolution (avec backtrack lorsqu'on tombe sur une incohérence).

Je n'ai pas regardé en détails le programme de Florent, mais je crois que le principe est assez voisin (mais il a quelques règles intelligentes en plus). Le programme (que je donne pour ceux qui veulent voir à quoi ressemble du Ruby, ou pour ceux qui veulent débuter un meilleur solveur de Sudoku) attend une grille au format texte, comme celles de Laurent, sur son entrée standard.

RMI, Java...

Lorsqu'on veut créer un objet distant avec Java/RMI (i.e. un objet compilable avec rmic), il ne suffit pas de dériver d'une classe qui implémente java.rmi.Remote, il faut que l'objet implémente directement une interface qui dérive de java.rmi.Remote. Ne me demandez pas pourquoi, mais c'est comme ça, et ça peut être bien de le retenir pour éviter de tourner en rond... À noter qu'il faut aussi que l'objet descende de UnicastRemoteObject.

J'ai dû installer une vieille version de Java sur ma Gentoo : ça ne marchait pas lors du lancement du fichier .bin auto-extractible, en raison d'une syntaxe non reconnue de tail : au début du .bin, il y a un tail +292 $0.... Le changer en tail -n +292.... Ensuite, le programme m'a indiqué des erreurs de checksum. Dans ce cas, lancer directement à la main le fichier install.sfx.* généré... Ce n'est pas grand-chose, mais si ça peut éviter des galères à certains...

Joies des generics

Voici un problème de Java qui a l'air insoluble : je veux faire une méthode qui me renvoie un tableau d'un type générique T, sachant que pour générer ledit tableau, j'utilise temporairement un ArrayList<T>. Problème : comment récupérer de façon type safe le tableau à partir de l'ArrayList<T>, sachant que je dispose d'une méthode toArray() qui renvoie un Object[] et toArray(T[]) qui renvoie un T[] ?

Première idée

public static <T> T[] truc(T a) {
	List<T> liste = new ArrayList<T>();
	liste.add(a);
	return liste.toArray(new T[] {});
}

Ça ne compile pas, parce que Java ne peut pas instancier de tableaux du type paramètre T (en raison de l'erasure, i.e. la suppression des types paramètres lors de la compilation, la JVM ne saurait tout simplement pas quelle classe instancier[1]).

Deuxième idée

Étant incapable d'instancier un T[], je décide donc de me rabattre sur la méthode qui me renvoie un Object[], et caster vers T[] :

	...
	return (T[]) liste.toArray();
	...

Sauf que le compilateur Java génère un warning « unchecked cast ». Ça compile et ça marche, mais on perd la type safety (qui n'est garantie que la compilation du projet entier ne génère aucun « unchecked cast »).

Des idées meilleures qu'un @SuppressWarnings("unchecked") ?

Notes

[1] Java interdit aussi l'instanciation de types génériques du genre List<String>[], mais c'est un autre problème, lié à la covariance des tableaux... Les deux problèmes sont très bien expliqués chez IBM.

Server Spy, développement, etc.

Grâce à de nombreux retours, j'ai pu corriger des bugs dans Server Spy et proposer une version 0.1.1. Le reviewer du site Firefox Add-ons a été très réactif, mais lorsqu'il s'est agi de propager le nouveau fichier sur le FTP, il y a eu quelques minutes de retard, d'où l'angoisse d'un utilisateur !

Ceci me conduit à un début de liste de « trucs » pour le développement d'extensions à Mozilla:

  • le livre « Creating Applications with Mozilla » (O'Reilly) est très bien. Même s'il date un peu (2002), il est en grande partie toujours d'actualité pour Firefox 1.5. Par contre, attention, il y a pas mal de typos (mauvaise capitalisation des noms de fonction notamment), donc il faut faire attention ;
  • sur le web, developer.mozilla.org, XUL Planet ;
  • l'extension FireBug est très pratique pour détecter les exceptions JavaScript levées par ses extensions ;
  • il y a plein de bonnes choses dans l'Extension Developer Extension, notamment le très pratique « reload all chrome ». Ceci dit, cette fonction m'a créé quelques soucis (perte de contexte JavaScript) ;
  • lorsqu'on teste une extension, penser à désactiver toutes les autres extensions. J'en étais ainsi venu à croire que Server Spy marchait correctement, alors que ce n'était pas le cas si une extension manquait (je n'ai même pas pu identifier laquelle...)

En parlant de développement, un geek de mes amis a publié des choses intéressantes : solveur de Sudoku en Java, logueur d'URL qui passent sur IRC en Perl.

Server Spy

Ma première extension pour Firefox (1.5 et plus) est disponible. Elle s'appelle Server Spy, et affiche le nom des serveurs web (Apache, IIS, etc.) qui propulsent les sites web visités. Pour un onglet donné, le nom du serveur est indiqué en bas à droite, dans la barre d'état de Firefox. Bref, un truc de geek :-)

Si vous l'essayez, n'hésitez pas à m'envoyer vos rapports de bugs et vos demandes de fonctionnalités.

Mise à jour (9 février, 19h45) : Server Spy est désormais distribué sur Mozilla Update. En quelques heures, plein de téléchargements, des commentaires sympas, des suggestions, un rapport de bug, que demande le peuple ? Ce qui m'embête par contre, c'est que je n'arrive pas à reproduire le bug qui m'a été signalé...

Valid XHTML 1.0 Strict © Christophe Jacquet.
Propulsé par DotClear.