Ecouter les messages DBus via GIO


Salut tout le monde 🙂 Aujourd’hui je vous propose un tuto qui explique comment utiliser DBus via GIO, plus précisément comment écouter les messages DBus qui transitent sur votre ordi. Peut-être que plus tard, je posterai aussi quelque chose pour expliquer comment faire pour l’émission 😉

J’écris ce tuto parce que j’en ai malheureusement trouvé aucun sur le net, et que la doc de GIO me parait assez hardcore, surtout les débutants dans l’utilisation de DBus, comme moi (avant :D).

C’est quoi tout ça ?

DBus, en gros c’est un programme qui se charge de la communication entre les autres programmes. C’est utilisé par exemple pour que Pidgin « capte » la chanson qui est écoutée en ce moment par Rhythmbox  et puisse faire chier le monde à mettre à jour votre message perso toutes les 0.3 seconde avec le nom de la chanson que vous « zappiez » parce que vous avez envie de passer de Blink 182 à Rammstein en utilisant uniquement la touche « piste suivante » de votre clavier. C’est aussi extrêmement utilisé par les systèmes Unix pour par exemple savoir la charge restante de la batterie, être averti du branchement d’un nouveau périphérique, mais aussi pour la modification de la luminosité de l’écran ou tout autres interactions avec le noyau. Si vous voulez plus de précision sur le sujet, vous pouvez toujours voir le howto officiel, la page Wikipédia, l’article sur Unix Garden, ou toutes autres pages web que vous trouverez avec peu d’effort sur Google.

GIO, quand à lui est une API développé pour un peu simplifier la vie aux utilisateurs de C (Ahhh oui, je vous l’avais pas dit, mais le tuto est codé en C :D) par la communauté GTK / Gnome. En fait, il s’agit d’une partie de GLib. Comme me l’a si bien expliqué mon cher-ami-ex-prof-de-réseaux, GIO est à GLib ce que System.IO est à .NET, et GLib est au C ce que .NET et au C# (En espérant que vous voyez ce qu’est .NET et C#, si non, c’est pas la peine de chercher, c’est le maaal :D). J’ai déjà mis le lien plus haut dans l’article, mais pour ceux qui l’aurait manqué : la doc de GIO, et plus précisément, la partie de la doc de GIO sur DBus. Si non, si vous avez l’habitude de développer sous environnement GTK, je vous conseil devhelp, une appli sympa pour recenser toute la doc en local qui vous sera utile 😉

Allons s’y !

Si à vous aussi ces quelques lignes vous on fait découvrir le but de votre vie et que vous êtes maintenant sur-motivé pour utiliser DBus dans toutes vos tâches courantes : monitorer d’autres applications, créer votre propre greffon pour avoir afficher en temps réel l’utilisation du processeur et de RAM de votre PC sur votre téléphone, mais bien plus encore ! Comme créer un réseau social sur votre bécane pour que vos applications peuvent partager leurs niveaux de consommation, leurs divers plantages mais aussi leurs nouveaux plug-in (hmm, hmm) du moment avec leurs amis applications, ou encore, de changer la vitesse de rotation des ventilos de votre ordi en fonction des messages que vous recevez sous Gajim, mais aussi en fonction de l’heure à laquelle est programmé votre réveil sur votre N900, DBus est fait pour vous, et mon tuto doit constituer une base plus ou moins correcte pour votre long et dangereux périple 😀

Pour capter comment tout ça fonctionne, je vous propose de faire un truc encore plus inutile que mes exemples ci-dessus : créer un programme externe à Rhythmbox qui affichera dans une console où vous en êtes dans la lecture d’une musique 😀 … Comment ça c’est nul ? Je vous signale que la vie elle même est nulle vu que son seul but et de nous faire patienter comme des cons jusqu’à notre mort, donc je vous conseil de très vite commencer à aimer ce genre de choses si vous ne voulez pas finir dépressif – suicidaire – suicidé, et du coup être victime d’une vie encore plus nulle que la moyenne ><

Monitorer les messages DBus

Sous Linux, il existe une commande pas mal qui permet d’afficher tout, ou seulement une partie du trafic DBus qui transite sur l’ordi sur le quel elle est exécutée, il s’agit de dbus-monitor. Ne me demandez pas comment fonctionne le filtre, j’en sais trop rien, je n’ai pas eu à les utiliser. Comment faire ensuite pour intercepter un message ? Il suffit d’attendre qu’une application en émette un et son intégralité sera écrit dans la console dans laquelle est exécuté dbus-monitor. Bien sur, si vous appliquez un filtre le message ne serra visible que si l’émission concorde ^^ Ainsi, si vous utilisez Gajim comment client XMPP, quand Bestah’ vient aux news, on peut apercevoir un message DBus qui ressemble à ça :

signal sender=:1.12 -> dest=(null destination) serial=667 path=/org/gajim/dbus/RemoteObject; interface=org.gajim.dbus.RemoteInterface; member=NewMessage
array [
variant          string « gnubox.eu »
variant          array [
variant                string « fourchuDu57@gnubox.net/msn »
variant                string « yo salut ! zyva la wesh wesh ou quoi ?? »
variant                int32 0
variant                int32 0
variant                string « chat »
variant                int32 0
variant                string « active »
variant                int32 5660
variant                string « XEP-0022 »
variant                string «  »
variant                int32 0
variant                int32 0
]
]

On y aperçoit plusieurs informations. Tout d’abord, des infos relative à l’identification du message (la première ligne), puis le contenu du-dit message. Normalement vous avez du passer de longues heures à lire les différentes pages que j’ai linké plus haut. La ligne d’identification ne doit donc pas vraiment vous poser de problème. Et si jamais c’est encore le cas, relisez le paragraphe 1.3 de l’article sur Unix Garden 😉

Les autres lignes relayent donc le contenu du message. Ici il est de type « av », pour « array of variant ».  Si cette phrase vous inspire autant qu’un koala qui fait du toboggan, relisez la partie « Using Remote Objects » du tuto officiel, ou bien cette page.

Bon.. Vous avec de la chance, le signal Rhythmbox qui nous intéresse est plus simple que celui présenté ci-dessus parce qu’il ne possède qu’un entier. Le message n’a en effet pour unique but que de spammer DBus en envoyant l’avancement en secondes de la chanson que vous êtes en train d’écouter. Le signal ressemble à ça :

signal sender=:1.17 -> dest=(null destination) serial=48 path=/org/gnome/Rhythmbox/Player; interface=org.gnome.Rhythmbox.Player; member=elapsedChanged
uint32 62

Ainsi, je suis actuellement à 1 minute et 2 secondes de lecture de ma chanson ! Magnifique n’est ce pas ?

Capturer un message DBus

Pour commencer, le code minimal d’une application qui utilise GIO, et qui boucle indéfiniment  ressemble à ça:

#include <gio/gio.h>

int main(int argc, char **argv) {
    //Initialisation de GIO
    g_type_init();
    //Création d'une boucle dans laquelle le programme bouclera indéfiniment
    GMainLoop *loop = g_main_loop_new(NULL, FALSE);

    // *** code à rajouter ***

    //Entré dans la boucle
    g_main_loop_run(loop);
    return 0;
}

Moui, je pense moi aussi qu’on aurait pu utiliser un while(1) pour la boucle, m’enfin, si déjà on a des outils méga cool pour faire ça, autant les utiliser, c’est plus performant apparemment. Il n’y a pas grand chose à rajouter, c’est du très basique pour le moment. Ahh si, pour compiler du GIO avec gcc, vous pouvez utiliser cette commande :

gcc fichier.c `pkg-config --cflags --libs gio-unix-2.0`

On va passer à la connexion de notre appli aux messages DBus que l’on veut écouter. Pour ce faire, on utilisera la fonction g_dbus_connection_signal_subscribe. On voit que cette fonction prend un assez gros paquet de paramètres :

  • Le premier consiste en une connexion DBus. On utilisera la fonction g_bus_get_sync pour cela. Les paramètres à utiliser ? Bah, le premier c’est G_BUS_TYPE_SESSION comme Rhythmbox est une application de la session et pas du système, le deuxième, on va dire NULL, ça fonctionne très bien, et comme troisième un double-pointeur de GError quelconque.
  • Le second est une chaîne de caractère qui contient le nom de l’application qu’on devra écouter. Dans notre cas, il s’agit de org.gnome.Rhythmbox. Il s’agit en général du début de la chaîne appelée « interface », jusqu’après le nom réel du programme.
  • Pour le troisième paramètre, il suffit de recopier bêtement la valeur après « interface » dans dbus-monitor, soit  org.gnome.Rhythmbox.Player
  • Cet argument consiste en quelque sorte, au nom du signal à capter. Il faut recopier la valeur « member » du signal : elapsedChanged
  • Encore un argument simple à trouver : le path du signal. Vous l’auriez deviné : org/gnome/Rhythmbox/Player
  • Je n’ai pas très bien compris à quoi servait ce sixième argument, mais ça fonctionne très bien avec la valeur NULL
  • Le septième argument est… inutilisé pour le moment. Donc on va pas se faire chier et on va mettre la valeur 0 (zéro).
  • L’argument le plus important : la fonction à appeler une fois un message capté. Attention au cast, on attend un pointeur de type GDBusSignalCallback. On appellera cette fonction « temps_lecture ». La valeur de l’argument est donc : (GDBusSignalCallback)temps_lecture
  • Le prochain consiste en un pointeur pointant sur des données quelconque qu’on serrait susceptible d’utiliser dans la fonction temps_lecture. On en aura pas besoin, on renseignera donc un pointeur NULL appelé, disons : donnees
  • Enfin, comme dernier argument il semblerait qu’il s’agisse d’une fonction à appeler quand la connexion avec l’objet DBus est terminée, un genre de destructeur quoi. Malheureusement, j’ai pas étudié cette partie de GIO, on va donc mettre NULL pour le moment.

En résumé, voilà ce qu’il faut rajouter au code d’avant (à la place de ***code à rajouter ***) :

//Le GError utile pour la connexion
GError **erreur = NULL;
//Le pointeur qui aurait pu contenir des données à transmettre à la fonction appelée
gpointer *donnees = NULL;

g_dbus_connection_signal_subscribe(
    g_bus_get_sync(G_BUS_TYPE_SESSION,    //Connexion au bus session
        NULL,                             //Utilité inconnue
        erreur),                          //Pointeur vers un GError, pour retourner l'erreur en cas de problème
    "org.gnome.Rhythmbox",                //Nom de l'application à "surveiller"
    "org.gnome.Rhythmbox.Player",         //Interface de l'application
    "elapsedChanged",                     //Membre du signal
    "/org/gnome/Rhythmbox/Player",        //Path de la fonction emmetrice
    NULL,                                 //Utilité inconnue
    0,                                    //Paramètre inutilisé
    (GDBusSignalCallback)temps_lecture,   //Fonction à appeler dès un message capté
    donnees,                              //Pointeur contenant des données à transmettre
    NULL);                                //Utilité inconnue

C’est pas la peine de compiler le code pour le moment, vous aurez une erreur. Si vous vous demandez pourquoi, je vous conseil de relire un peu plus attentivement la description des paramètres de la fonction g_dbus_connection_signal_subscribe, et plus particulièrement le paramètre 8 😉 Eh oui, pour le moment, la fonction temps_lecture n’existe pas, nous allons donc l’implémenter :p

La fonction est sensée être de la forme GDBusSignalCallBack, à savoir, ne rien retourner (fonction de type void) et avoir les mêmes paramètres. Pourquoi imposer ce modèle ? Certainement parce que la fonction g_dbus_connection_signal_subscribe est configurée pour retourner ces paramètres, dans l’ordre donné à GDBusSignalCallback. Après j’en suis pas sur, si vous avez plus de précisions à ce sujet, votre savoir sera le bienvenu ici 😉 On ne va donc pas faire compliqué et utiliser le même en-tête que dans la donc GIO pour notre fonction :

void temps_lecture (GDBusConnection *connec, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *param, gpointer *data)

Pour la liste des paramètres, tout est expliqué dans la doc, on remarquera que les cinq premiers identifient le signal. Il est donc tout à fait possible d’appeler la même fonction pour plusieurs signaux différent, avec un traitement approprié à chacun d’eux. Le contenu du message sera stocké dans le GVariant, et enfin le dernier paramètre contient un pointeur vers les données qu’on a passé à la fonction « manuellement » via le gpointer de g_dbus_connection_signal_subscribe.

Extraire les informations du GVariant

En fait, le GVariant est un conteneur qui peut contenir des données de n’importe quel type. Pour voir ce que contient un GVariant, on peu utiliser la fonction g_variant_get_type_string qui retournera une chaîne de caractère avec des valeurs expliqués ici.

Du coup, on va pouvoir implémenter une « version » de temps_lecture qui se chargera de retourner le type du GVariant reçu à chaque message :

void test (GDBusConnection *connec, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *param, gpointer *data) {
	//Création du string contenant le type de GVariant
	const gchar *type_GVariant = g_variant_get_type_string(param);
	//Affichage du type
	g_print("Le type du GVariant est : %s !\n", type_GVariant);
}

Le code source complet du programme est dispo ici : http://pastebin.archlinux.fr/432266

Si vous compilez, exécutez ce programme, puis écoutez de la musique avec Rhythmbox, vous devriez obtenir une sortie du genre :

Le type du GVariant est : (u) !
Le type du GVariant est : (u) !
Le type du GVariant est : (u) !
Le type du GVariant est : (u) !
Le type du GVariant est : (u) !
Le type du GVariant est : (u) !

Et ainsi de suite, avec un nouveau message toutes les secondes jusqu’à ce que vous stoppiez la musique. Nous apprenons donc que le type de notre GVariant est (u), soit un tuple d’un entier non signé de 32 bits (on retiendra : un entier). Vous remarquerez qu’il s’agit du même type que celui indiqué par dbus-monitor plus haut, heureusement hein ? ^^

Maintenant qu’on sait qu’on reçois un entier de notre message DBus, comment le récupérer ? A l’aide de la fonction g_variant_get. Elle fonctionne un peu comme scanf. Elle ne retourne rien, niveau paramètres, dans un premier temps on renseigne le GVariant à extraire, puis un string qui décrit le type de contenu présent dans le GVariant (en gros, ce qu’on affichait avant avec la fonction g_variant_get_type_string, à savoir (u) ), et enfin des adresses vers les variables dans les quels nous devons stocker nos valeurs, de préférence du même type que la variable extraite. Dans notre cas, il s’agit donc d’un unique pointeur de gint. On va donc pouvoir réaliser  notre objectif ultime de ce tuto : afficher en temps réel l’avancement de notre musique ! 😀 Pour ce faire on va modifier la fonction temps_lecture pour réaliser cette tache :

void temps_lecture (GDBusConnection *connec, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *param, gpointer *data) {
	//La variable qui contiendra l'avancement de la lecture en secondes
	gint avancement;
	//Extraction du gvariant dans la variable
	g_variant_get(param, "(u)", &avancement);
	//Ecriture de l'avancement
	g_print("Lecture : %d minutes et %d secondes\n", avancement / 60, avancement % 60);
}

Ce programme complet est dispo ici : http://pastebin.archlinux.fr/432267. Une fois compilé / exécuté / en-écoute-d’une-chanson, vous devriez avoir comme sortie quelque chose du genre :

Lecture : 3 minutes et 5 secondes
Lecture : 3 minutes et 6 secondes
Lecture : 3 minutes et 7 secondes
Lecture : 3 minutes et 8 secondes
Lecture : 3 minutes et 9 secondes

Et ainsi de suite, avec une nouvelle ligne toutes les secondes jusqu’à la fin des temps (ou que la playlist soit terminée, ou que Rhythmbox plante, ou que votre ordi crash).

Hé voila ! Vous savez maintenant comment intercepter des messages DBus et les réutiliser ! 😀 Super cool hein ?

Les GVariants de type « array of content »

Attention, attention : cette partie résulte de mes expériences personnelles réalisées sur le sujet. La véracité des informations communiquée n’est pas garantie. Il ne s’agit que d’une conclusion qui représente ce que je pense avoir compris du sujet !

Pour ma part, c’est la partie qui m’a prise le plus de temps dans tout l’apprentissage que j’ai fais pour le moment sur DBus et GIO. Reprenons le signal DBus présenté plus haut, celui émit à la réception d’un nouveau message par Gajim. On voit bien que le GVariant est découpé en deux parties : la première, qui possède un string (de valeur « gnubox.eu »), et le second, un autre « array of content » qui lui même contient des strings et des entiers. Ce schéma doit vous mettre les idées au clair :

Pour utiliser ce type de GVariant, il faut au préalable sortir les fils du GVariant père. Pour cela, il existe une fonction qui s’appelle : g_variant_get_child_value, qui prend comme premier paramètre le GVariant père et en second le fils à extraire (Attention ça commence à zéro, donc pour le 1er fils, il faut marquer 0 (zéro), pour le second 1, etc.). La fonction retourne donc le GVariant fils. Le programme ci-dessous est sensé retourner le 1er fils du GVariant ci-dessus soit un de type string (s). Pour le débogage, on utilisera la fonction g_variant_print qui permet d’afficher en brut le contenu d’un GVariant :

void temps_lecture (GDBusConnection *connec, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *param, gpointer *data) {
	//Création du fils
	GVariant *premierFils = g_variant_get_child_value(param, 0);
	//Exportation du contenu du fils
	char *contenu = g_variant_print(premierFils, TRUE);
	//Type du fils
	char *type = g_variant_get_type_string(premierFils);
	//Ecriture
	g_print("#### Type : %s\n#### Contenu : %s", type, contenu);
}

Et le résultat obtenu après la réception d’un nouveau message :

#### Type : av
#### Contenu : [<‘gnubox.eu’>, <[<‘fourchuDu57@gnubox.net/msn’>, <‘yo salut ! zyva la wesh wesh ou quoi ??’>, <0>, <0>, <‘chat’>, <0>, <‘active’>, <5660>, <‘XEP-0022’>, < »>, <0>, <0>]>]

Bizarre, n’est ce pas ? Quand j’ai fais ce test pour la première fois, je me suis demandé de quelle planète débarquai les développeurs de GIO. Après tout, faut quand même avoué qu’être son propre père… C’est pas humain 😀 J’ai compris un peu (à vrais dire, 3 jours plus tard -_-« ) mon erreur. Voici le retour d’une fonction qui affiche le type de param (le GVariant père)  et celui du de premierFils :

#### Type père : (av)
#### Type fils : av

Vous comprenez ? En fait, il y a plus d’étapes dans la « hiérarchie des fils » que ce qu’on pourrait penser à première vue. La chaîne « gnubox.eu » n’est en effet pas un fils de param mais un petit-petit-fils ! Un vrais scoop hein ? 😮 En effet, il faut faire encore deux g_variant_get_chid_value sur premierFils pour atteindre le string recherché. Pourquoi ça ? A mon avis, ça vient d’une mauvaise lecture de ma part du contenu du message. En effet, si on lit vraiment la ligne sur dbus-monitor qui nous parle de « gnubox.eu », on voit qu’il s’agit en fait d’une string qui est contenu dans un variant qui lui même est contenu dans un autre variant qui est dans un tableau. Oui, on a quelque chose qui ressemble à ça :

Pour un souci de lisibilité j’ai nommé les variables en fonction du niveau des enfants qu’ils représentent. Le niveau zéro correspond au paramètre param donné à l’appel de la fonction. Voici le code C correspondant :

void test_gvariant (GDBusConnection *connec, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *param, gpointer *data) {
	//Création des fils
	GVariant *un = g_variant_get_child_value(param, 0);
	GVariant *deux = g_variant_get_child_value(un, 0);
	GVariant *trois = g_variant_get_child_value(deux, 0);

	//Type des GVariant
	gchar *tzero = g_variant_get_type_string(param);
	gchar *tun = g_variant_get_type_string(un);
	gchar *tdeux = g_variant_get_type_string(deux);
	gchar *ttrois = g_variant_get_type_string(trois); 

	//Contenu des GVariant
	gchar *vzero = g_variant_print(param, TRUE);
	gchar *vun = g_variant_print(un, TRUE);
	gchar *vdeux = g_variant_print(deux, TRUE);
	gchar *vtrois = g_variant_print(trois, TRUE);

	//Ecriture
	g_print("#### Zero %s : %s\n#### Un %s : %s\n#### Deux %s : %s\n#### Trois %s : %s\n", tzero, vzero, tun, vun, tdeux, vdeux, ttrois, vtrois);
}

Qui nous donne comme sortie :

#### Zero (av) : ([<‘gnubox.eu’>, <[<‘fourchuDu57@gnubox.net/msn’>, <‘yo salut ! zyva la wesh wesh ou quoi ??’>, <0>, <0>, <‘chat’>, <0>, <‘active’>, <5660>, <‘XEP-0022’>, < »>, <0>, <0>]>],)
#### Un av : [<‘gnubox.eu’>, <[<‘fourchuDu57@gnubox.net/msn’>, <‘yo salut ! zyva la wesh wesh ou quoi ??’>, <0>, <0>, <‘chat’>, <0>, <‘active’>, <5660>, <‘XEP-0022’>, < »>, <0>, <0>]>]
#### Deux v : <‘gnubox.eu’>
#### Trois s : ‘gnubox.eu’

Hé ouais, complexe n’est ce pas ? Pour finir, on va tenter de capturer le contenu des nouveaux messages entrants (donc pour cet exemple « yo salut ! zyva la wesh wesh ou quoi ?? »), vous allez voir, c’est pire que les feux de l’amour niveau gosses et papa ^^

Et le code C qui correspond à ça :

void test_gvariant (GDBusConnection *connec, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, const gchar *signal_name, GVariant *param, gpointer *data) {
	//Création des fils
	GVariant *un = g_variant_get_child_value(param, 0);
	GVariant *deux = g_variant_get_child_value(un, 1);
	GVariant *trois = g_variant_get_child_value(deux, 0);
	GVariant *quatre = g_variant_get_child_value(trois, 1);
	GVariant *cinq = g_variant_get_child_value(quatre, 0);

	//Type des GVariant
	gchar *tzero = g_variant_get_type_string(param);
	gchar *tun = g_variant_get_type_string(un);
	gchar *tdeux = g_variant_get_type_string(deux);
	gchar *ttrois = g_variant_get_type_string(trois);
	gchar *tquatre = g_variant_get_type_string(quatre);
	gchar *tcinq = g_variant_get_type_string(cinq);

	//Contenu des GVariant
	gchar *vzero = g_variant_print(param, TRUE);
	gchar *vun = g_variant_print(un, TRUE);
	gchar *vdeux = g_variant_print(deux, TRUE);
	gchar *vtrois = g_variant_print(trois, TRUE);
	gchar *vquatre = g_variant_print(quatre, TRUE);
	gchar *vcinq = g_variant_print(cinq, TRUE);

	//Ecriture
	g_print("#### Zero %s : %s\n#### Un %s : %s\n#### Deux %s : %s\n#### Trois %s : %s\n#### Quatre %s : %s\n#### Cinq %s : %s\n", tzero, vzero, tun, vun, tdeux, vdeux, ttrois, vtrois, tquatre, vquatre, tcinq, vcinq);
}

Et la sortie console :

#### Zero (av) : ([<‘gnubox.eu’>, <[<‘fourchuDu57@gnubox.net/msn’>, <‘yo salut ! zyva la wesh wesh ou quoi ??’>, <0>, <0>, <‘chat’>, <0>, <‘active’>, <5660>, <‘XEP-0022’>, < »>, <0>, <0>]>],)
#### Un av : [<‘gnubox.eu’>, <[<‘fourchuDu57@gnubox.net/msn’>, <‘yo salut ! zyva la wesh wesh ou quoi ??’>, <0>, <0>, <‘chat’>, <0>, <‘active’>, <5660>, <‘XEP-0022’>, < »>, <0>, <0>]>]
#### Deux v : <[<‘fourchuDu57@gnubox.net/msn’>, <yo salut ! zyva la wesh wesh ou quoi ??’>, <0>, <0>, <‘chat’>, <0>, <‘active’>, <5660>, <‘XEP-0022’>, < »>, <0>, <0>]>
#### Trois av : [<‘fourchuDu57@gnubox.net/msn’>, <‘yo salut ! zyva la wesh wesh ou quoi ??’>, <0>, <0>, <‘chat’>, <0>, <‘active’>, <5660>, <‘XEP-0022’>, < »>, <0>, <0>]
#### Quatre v : <‘yo salut ! zyva la wesh wesh ou quoi ??’>
#### Cinq s : ‘yo salut ! zyva la wesh wesh ou quoi ??’

Bien sur, pour utiliser le contenu final, soit ici le texte reçu de l’utilisateur, il ne faut pas passer par g_variant_print mais par g_variant_get_child, comme expliqué plus haut. g_variant_print doit être utilisé que pour le débogage. Voici le code complet du dernier exemple : http://pastebin.archlinux.fr/432265

Le mot de la fin

Hé voila, c’est tout pour aujourd’hui 🙂 J’espère que vous avez compris quelque chose à mon article et qu’à présent vous maîtrisez le côté DBus de GIO comme des pros 😛 Si vous avez des questions, vous pouvez toujours les poser en commentaire. Bien sur, toutes autres remarques ou précisions sur le sujet sont aussi les bienvenues. Je ne suis pas très expérimenté en la matière, j’ai appris tout ça en une semaine, donc il risquerai d’y avoir des explications inexactes (surtout la dernière partie) malgré tout les efforts que j’ai fourni pour en faire le moins possible. Si c’est le cas, je vous serez également reconnaissant de le signaler ! 😉

A la prochaine !