<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog du projet ZiK &#187; debian-fr</title>
	<atom:link href="https://blog.developpez.com/zik/pcategory/debian-fr/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/zik</link>
	<description></description>
	<lastBuildDate>Wed, 14 Dec 2011 16:32:19 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>Adapter une bibliothèque C pour ruby (1)</title>
		<link>https://blog.developpez.com/zik/p9266/ruby/adapter_une_bibliotheque_c_pour_ruby_1</link>
		<comments>https://blog.developpez.com/zik/p9266/ruby/adapter_une_bibliotheque_c_pour_ruby_1#comments</comments>
		<pubDate>Fri, 01 Oct 2010 15:17:24 +0000</pubDate>
		<dc:creator><![CDATA[vinc-mai]]></dc:creator>
				<category><![CDATA[debian-fr]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Introduction J&#8217;utilise régulièrement ruby-taglib. Malheureusement, certains bugs empêchent son utilisation avec ruby 1.9. Après avoir tenté, avec plus ou moins de succès, de corriger ces bugs, j&#8217;ai décidé de réécrire cette bibliothèque. La version originale est basée sur ruby/DL, bibliothèque que je n&#8217;ai jamais utilisée. Je profite de cette réécriture pour proposer une série d&#8217;articles sur la manière d&#8217;adapter une bibliothèque C. Préparation Je développe pour l&#8217;instant sous ubuntu 10.04 (je terminerai sûrement ces articles [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>
J&rsquo;utilise régulièrement <a href="http://www.hakubi.us/ruby-taglib/">ruby-taglib</a>. Malheureusement, certains bugs empêchent son utilisation avec ruby 1.9. Après avoir tenté, avec plus ou moins de succès, de corriger ces bugs, j&rsquo;ai décidé de réécrire cette bibliothèque. La version originale est basée sur <a href="http://ttsky.net/ruby/ruby-dl.html">ruby/DL</a>, bibliothèque que je n&rsquo;ai jamais utilisée. Je profite de cette réécriture pour proposer une série d&rsquo;articles sur la manière d&rsquo;adapter une bibliothèque C.
</p>
<p><span id="more-14"></span></p>
<h2>Préparation</h2>
<p>
Je développe pour l&rsquo;instant sous ubuntu 10.04 (je terminerai sûrement ces articles sous la version 10.10). J&rsquo;ai installé <a href="http://developer.kde.org/~wheeler/taglib.html">taglib</a>, ruby et rdoc soit les paquets debian suivant : libtagc0, libtagc0-dev, ruby, ruby-dev, rdoc.
</p>
<h2>Hiérarchie</h2>
<p>
La commande <b>tree</b> présente l&rsquo;arborescence de mon répertoire de travail.
</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ tree <br />
. <br />
&amp;#9500;&amp;#9472;&amp;#9472; extconf.rb <br />
&amp;#9500;&amp;#9472;&amp;#9472; lib <br />
&amp;#9474;   &amp;#9492;&amp;#9472;&amp;#9472; taglib2.rb <br />
&amp;#9492;&amp;#9472;&amp;#9472; taglib2.c</div></div>
<p>
Le fichier <b>extconf.rb</b>, écrit en ruby, permettra de préparer les sources en vue de compiler la bibliothèque. Le fichier <b>lib/taglib2.rb</b>, lui aussi écrit en ruby, est le fichier lu par l&rsquo;interpréteur ruby lors de l&rsquo;appel à <b>require &laquo;&nbsp;taglib2&Prime;</b> qui chargera notre future bibliothèque.Le fichier <b>taglib2.c</b>, écrit en C, contiendra les méthodes qui permettent d&rsquo;interfacer taglib.
</p>
<h2>Ruby</h2>
<p>
Dans un premier temps, j&rsquo;utiliserai seulement le langage ruby. J&rsquo;écris donc les premières lignes de code dans le fichier <b>lib/taglib2.rb</b>.
</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ cat lib/taglib2.rb &nbsp;<br />
module TagLib <br />
&nbsp; VERSION=[0, 0, 1] <br />
end</div></div>
<p>
Une constante nommée <b>VERSION</b> est définie comme un tableau contenant 3 entiers. D’ores et déjà, je peux tester mon code grâce à irb, un interpréteur ruby en ligne de commande. La bibliothèque n&rsquo;étant pas encore installée, j&rsquo;utilise un chemin relatif pour y accéder.
</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ irb <br />
&gt; require &quot;./lib/taglib2&quot; <br />
=&gt; true <br />
&gt; TagLib::VERSION <br />
=&gt; [0, 0, 1]</div></div>
<h2>Interface ruby/C</h2>
<h3>Exceptions</h3>
<p>
Nous nous intéressons enfin au fichier <b>taglib2.c</b>. Nous définissons, tout d&rsquo;abord, les différents types d&rsquo;exceptions qui peuvent être levés par la bibliothèque.
</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ cat taglib2.c <br />
#include &lt;ruby.h&gt; <br />
#include &lt;taglib/tag_c.h&gt; <br />
&nbsp;<br />
VALUE mTagLib; <br />
VALUE eBadPath, eBadFile, eBadTag, eBadAudioProperties; <br />
&nbsp;<br />
void <br />
Init_taglib2() <br />
{ <br />
&nbsp; mTagLib=rb_define_module(&quot;TagLib&quot;); <br />
&nbsp; eBadPath=rb_define_class_under(mTagLib, &quot;BadPath&quot;, rb_eException); <br />
&nbsp; &nbsp; eBadFile=rb_define_class_under(mTagLib, &quot;BadFile&quot;, rb_eException); <br />
&nbsp; &nbsp; eBadTag=rb_define_class_under(mTagLib, &quot;BadTag&quot;, rb_eException); <br />
&nbsp; &nbsp; eBadAudioProperties=rb_define_class_under(mTagLib, &quot;BadAudioProperties&quot;, rb_eException); <br />
}</div></div>
<p>
Les fichiers nécessaires au développement de la bibliothèque sont tout d&rsquo;abord inclus puis nous déclarons des variables de type <b>VALUE</b>. Ce type est utilisé pour toute variable représentant un objet du langage ruby. Les noms de variables représentant des exceptions sont généralement préfixés par la lettre <b>e</b>. Pour les modules, la lettre <b>m</b> est utilisée, pour les classes, la lettre <b>c</b>.<br />
Il s&rsquo;agit d&rsquo;une convention et non d&rsquo;une règle. Finalement, on retrouve la fonction <b>Init_taglib2</b> qui (re)définit le module TagLib ainsi que 4 classes descendant de la classe ruby <b>Exception</b> représentée en C par la variable <b>rb_eException</b>.
</p>
<p>
Le code suivant, écrit en ruby, est équivalent à la définition donnée en C de l&rsquo;exception <b>TagLib::BadPath</b>
</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">module TagLib <br />
class BadPath &lt; Exception <br />
end <br />
end</div></div>
<h3>Compilation</h3>
<p>
Afin de compiler notre bibliothèque, nous devons créer un fichier <b>Makefile</b>. La bibliothèque <b>mkmf</b> nous facilite le travail.
</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ cat -n extconf.rb <br />
1 &nbsp;require 'mkmf' <br />
2 &nbsp;<br />
3 &nbsp;have_header('ruby.h') || exit 1 <br />
4 &nbsp;have_header('taglib/tag_c.h') || exit(1) <br />
5 &nbsp;<br />
6 &nbsp;create_makefile(&quot;taglib2&quot;) <br />
$ ruby extconf.rb &nbsp;<br />
checking for ruby.h... yes <br />
checking for taglib/tag_c.h... yes <br />
creating Makefile</div></div>
<p>
Dans le fichier <b>extconf.rb</b>, la présence des fichiers « header » de ruby et de taglib sont vérifiées ligne 3 et 4. La ligne 6 permet de créer le fichier <b>Makefile</b> du projet taglib2. Lors du chargement d&rsquo;une interface ruby/C, la fontion appelée est de la forme <b>Init_NomDuProjet</b>,c&rsquo;est pourquoi l&rsquo;unique fonction du fichier  <b>taglib2.c</b> s&rsquo;appelle <b>Init_taglib2</b>. Il s&rsquo;agit de l&rsquo;équivalent de la fonction <b>main</b> d&rsquo;un programme C traditionnel.
</p>
<p>
Après avoir créer le fichier Makefile, compilons.
</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ ruby extconf.rb <br />
$ make</div></div>
<p>
Un bibliothèque dynamique <b>taglib2.so</b> vient de faire son apparition. Ruby permet de charger directement ce type de bibliothèque. Nous ajoutons donc l&rsquo;instruction (<b>require &laquo;&nbsp;taglib2.so&nbsp;&raquo;</b>) de chargement dans le fichier <b>lib/taglib2.rb</b>.
</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ cat lib/taglib2.rb &nbsp;<br />
require &quot;taglib2.so&quot; <br />
&nbsp;<br />
module TagLib <br />
VERSION=[0, 0, 1] <br />
end</div></div>
<h3>Test</h3>
<p>
Nous testons notre code sous irb.
</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ irb <br />
&gt; $:.unshift('.') <br />
&gt; $:.unshift('lib') <br />
&gt; require &quot;taglib2&quot; <br />
=&gt; true <br />
&gt; TagLib.constants <br />
=&gt; [&quot;BadFile&quot;, &quot;BadPath&quot;, &quot;BadAudioProperties&quot;, &quot;VERSION&quot;, &quot;BadTag&quot;] <br />
&gt; TagLib::BadPath.new <br />
=&gt; #&lt;TagLib::BadPath: TagLib::BadPath&gt;</div></div>
<p>
J&rsquo;ajoute tout d&rsquo;abord le répertoire courant et le répertoire <b>lib</b> dans les chemins vérifiés lors du chargement d&rsquo;un fichier afin que les appels à <b>require &laquo;&nbsp;taglib2&Prime;</b> et à <b>require &laquo;&nbsp;taglib2.so&nbsp;&raquo;</b> n&rsquo;échouent pas. Cette astuce ne sera plus nécessaire une fois la bibliothèque installée. On vérifie que les constantes définies dans les fichiers sources <b>lib/taglib2.rb</b> et <b>taglib2.c</b> sont accessibles.
</p>
<h2>Conclusion</h2>
<p>
Lors de ce premier billet, j&rsquo;ai mis en place les différents éléments (bibliothèques, fichiers) qui seront nécessaires à l&rsquo;interface ruby de taglib. Nous avons, déjà, réussi à obtenir un code fonctionnel. Il nous reste à porter les fonctions proposées par taglib afin de pourvoir accéder, en ruby, aux tags de fichiers musicaux.<br />À la prochaine.
</p>
<p>
Je ne suis pas un spécialiste du langage C, si vous avez des suggestions à faire sur mon code<br />
commentez ce billet.
</p>
<h2>Addendum</h2>
<p>Je rajoute la liste des billets faisant suite à celui-ci :</p>
<ul>
<li><a href="http://blog.developpez.com/zik/p9343/ruby/adapter-une-bibliotheque-c-pour-ruby-2/">billet 2</a>,</li>
<li><a href="http://blog.developpez.com/zik/p9348/ruby/adapter-une-bibliotheque-c-pour-ruby-3/">billet 3</a>,</li>
<li><a href="http://blog.developpez.com/zik/p9357/ruby/adapter-une-bibliotheque-c-pour-ruby-4/">billet 4</a>,</li>
<li><a href="http://blog.developpez.com/zik/p9360/ruby/adapter-une-bibliotheque-c-pour-ruby-5/">billet 5</a>.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>ZiK 0.15.2</title>
		<link>https://blog.developpez.com/zik/p9370/debian-fr/zik_0_15_2</link>
		<comments>https://blog.developpez.com/zik/p9370/debian-fr/zik_0_15_2#comments</comments>
		<pubDate>Mon, 11 Oct 2010 15:18:08 +0000</pubDate>
		<dc:creator><![CDATA[vinc-mai]]></dc:creator>
				<category><![CDATA[debian-fr]]></category>
		<category><![CDATA[Nouvelle version]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Cette version corrige des bogues dans l&#8217;assistant and dans le module brainz qui peuvent provoquer la fermeture de ZiK. L&#8217;entrée « éditer » a disparu du menu « liste de lecture » car il provoque un bogue. La liste peut toujours être éditée via le boutton ou le menu contextuel.]]></description>
				<content:encoded><![CDATA[<p>Cette version corrige des bogues dans l&rsquo;assistant and dans le module brainz qui peuvent provoquer la fermeture de ZiK.<br />
L&rsquo;entrée « éditer » a disparu du menu « liste de lecture » car il provoque un bogue. La liste peut toujours être éditée via le boutton ou le menu contextuel.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sortie de ZiK 0.15</title>
		<link>https://blog.developpez.com/zik/p9367/debian-fr/sortie_de_zik_0_15</link>
		<comments>https://blog.developpez.com/zik/p9367/debian-fr/sortie_de_zik_0_15#comments</comments>
		<pubDate>Sat, 09 Oct 2010 17:03:17 +0000</pubDate>
		<dc:creator><![CDATA[vinc-mai]]></dc:creator>
				<category><![CDATA[debian-fr]]></category>
		<category><![CDATA[Nouvelle version]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[La version 0.15 de ZiK est sortie. Un assistant explique le fonctionnement de ZiK lors d&#8217;une nouvelle installation. Il permet aussi une configuration rapide du logiciel. Il est disponible via le menu aide. L&#8217;édition de la liste de lecture et la recherche de pistes audio sont maintenant intégrées à la fenêtre principale. La vue compact permet d&#8217;afficher un plus grand nombre de pistes audio dans la liste de lecture. ZiK supporte maintenant ruby-taglib2 et les [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>La version 0.15 de ZiK est sortie.</p>
<p>Un assistant explique le fonctionnement de ZiK lors d&rsquo;une nouvelle installation. Il permet aussi une configuration rapide du logiciel. Il est disponible via le menu aide.<br />
L&rsquo;édition de la liste de lecture et la recherche de pistes audio sont maintenant intégrées à la fenêtre principale.<br />
La vue compact permet d&rsquo;afficher un plus grand nombre de pistes audio dans la liste de lecture.<br />
ZiK supporte maintenant ruby-taglib2 et les nouvelles versions de rghk (0.2) et de gtk (2.22).<br />
La traduction française a été mise à jour.<br />
Pour plus d&rsquo;informations, voyer le fichier ChangeLog.</p>
<p>Téléchargez ZiK sur <a href="http://projets.developpez.com/projects/zik/files">developpez.com</a>.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Adapter une bibliothèque C pour ruby (5)</title>
		<link>https://blog.developpez.com/zik/p9360/ruby/adapter_une_bibliotheque_c_pour_ruby_5</link>
		<comments>https://blog.developpez.com/zik/p9360/ruby/adapter_une_bibliotheque_c_pour_ruby_5#comments</comments>
		<pubDate>Thu, 07 Oct 2010 16:26:01 +0000</pubDate>
		<dc:creator><![CDATA[vinc-mai]]></dc:creator>
				<category><![CDATA[debian-fr]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Diverses fonctions Je vais présenter ici quelques fonctions utiles. Pour des questions de faciliter, j&#8217;ai créé deux nouvelles méthodes pour le module TagLib bien qu&#8217;elles n&#8217;aient rien avoir avec taglib. Utiliser un bloc rb_define_singleton_method(mTagLib, &#34;block&#34;, block, 0); La méthode TagLib.block ne prend aucun paramètre, mais un bloc doit lui être fourni. Elle exécute ce bloc en lui passant comme argument l&#8217;objet TagLib et retourne le bloc sous la forme d&#8217;un Proc. $ make $ irb [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2>Diverses fonctions</h2>
<p>Je vais présenter ici quelques fonctions utiles. Pour des questions de faciliter, j&rsquo;ai créé deux nouvelles méthodes pour le module <b>TagLib</b> bien qu&rsquo;elles n&rsquo;aient rien avoir avec taglib.</p>
<h3>Utiliser un bloc</h3>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">rb_define_singleton_method(mTagLib, &quot;block&quot;, block, 0);</div></div>
<p>La méthode <b>TagLib.block</b> ne prend aucun paramètre, mais un bloc doit lui être fourni. Elle exécute ce bloc en lui passant comme argument l&rsquo;objet <b>TagLib</b> et retourne le bloc sous la forme d&rsquo;un <b>Proc</b>.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ make <br />
$ irb <br />
&gt; require './lib/taglib2.rb' <br />
=&gt; true <br />
TagLib.block{|a| p a} <br />
TagLib <br />
=&gt; #&lt;Proc:0xb75ba510@(irb):2&gt;</div></div>
<p>Voici la fonction implémentant ce comportement.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">VALUE <br />
block(VALUE self) <br />
{ <br />
&nbsp; &nbsp; rb_yield(self); <br />
&nbsp; &nbsp; return rb_block_proc(); <br />
}</div></div>
<p><b>rb_yield</b> permet d&rsquo;appeler le bloc passé à la méthode alors que <b>rb_block_proc</b> permet de le manipuler sous la forme d&rsquo;un <b>Proc</b>.</p>
<h3>Utiliser des paramètres optionnels</h3>
<p>Je propose d&rsquo;écrire l&rsquo;équivalent de code écrit en ruby.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">def TagLib.n(tab=[&quot;Salut&quot;, &quot;Re&quot;]) <br />
&nbsp; &nbsp; tab.to_a <br />
&nbsp; &nbsp; tab.each{|s| $stdout.puts s} <br />
&nbsp; &nbsp; tab[0] <br />
end</div></div>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">rb_define_singleton_method(mTagLib, &quot;n&quot;, n, -1);</div></div>
<p>Le dernier argument lors de la déclaration de la méthode <b>TagLib.n</b> vaut <b>-1</b> ce qui indique que la méthode ne possède pas un nombre d&rsquo;arguments fixees. La fonction <b>rb_scan_args</b> permet de récupérer de manière propre les paramètres passés à la méthode. Le troisième argument de cette fonction est une chaîne de caractère représentant deux chiffres. Le premier indique le nombre de paramètres obligatoires, le second indique le nombre de paramètres optionnels.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">VALUE <br />
n1(VALUE str) <br />
{ <br />
&nbsp; &nbsp; return rb_funcall(rb_stdout, rb_intern(&quot;puts&quot;), 1, str); <br />
} <br />
&nbsp;<br />
VALUE <br />
n(int argc, VALUE* argv, VALUE self) <br />
{ <br />
&nbsp; &nbsp; VALUE tab; <br />
&nbsp;<br />
&nbsp; &nbsp; rb_scan_args(argc, argv, &quot;01&quot;, &amp;tab); <br />
&nbsp; &nbsp; if (NIL_P(tab)) <br />
&nbsp; &nbsp; &nbsp; &nbsp; tab=rb_ary_new3(2, rb_str_new2(&quot;Salut&quot;), rb_str_new2(&quot;Re&quot;)); <br />
&nbsp; &nbsp; rb_funcall(tab, rb_intern(&quot;to_a&quot;), 0); <br />
&nbsp;<br />
&nbsp; &nbsp; rb_iterate(rb_each, tab, n1, Qnil); <br />
&nbsp; &nbsp; return RARRAY(tab)-&gt;ptr[0]; <br />
}</div></div>
<p><b>TagLib.n</b> peut donc être appelée avec un paramètre ou sans. Si aucun argument n&rsquo;a été passé (<b>tab=nil</b>), tab est initialisé en créant un tableau contenant deux objets <b>String</b>. On vérifie ensuite que <b>tab</b> appartient à la classe <b>Array</b> ou s&rsquo;en rapproche (<a href="http://fr.wikipedia.org/wiki/Duck_typing">duck typing</a>). <b>rb_funcall</b> permet d&rsquo;appeler une méthode (deuxième argument) d&rsquo;un objet (premier argument) avec un certain nombre (troisième argument) de paramètres (arguments suivant). <b>rb_intern</b> permet d&rsquo;obtenir la méthode à partir d&rsquo;une chaîne de caractères.<br />
La fonction <b>n1</b> est ensuite appelé pour chacun des éléments du tableau grâce à <b>rb_iterate</b>. LA méthode retourne, finalement, le premier élément de <b>tab</b>, la macro <b>RARRAY</b> permettant d&rsquo;accéder à la structure interne d&rsquo;un objet de la classe <b>Array</b>, le champ <b>ptr</b> permettant d&rsquo;accéder aux éléments.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&gt; TagLib.n <br />
Salut <br />
Re <br />
=&gt; &quot;Salut&quot; <br />
&gt; TagLib.n([&quot;Bonjour&quot;]) <br />
Bonjour <br />
=&gt; &quot;Bonjour&quot;</div></div>
<h2>Liens utiles</h2>
<p>Quelques liens qui m&rsquo;ont aidé à écrire des extensions pour ruby en C :<br />
le fichier README.EXt fourni avec ruby,<br />
<a href="http://ruby-doc.org/docs/ProgrammingRuby/html/ext_ruby.html">ruby-doc</a>.<br />
En ce qui concerne taglib :<br />
l&rsquo;exemple dans les sources de taglib,<br />
le fichier bindings/c/tag_c.h.</p>
<h2>Sources</h2>
<p>Le code, présenté dans ces billets, implémentant le module, <b>TagLib</b> est téléchargeable <a href="http://zik.developpez.com/blog/c_ext/source/taglib2.tar.bz2">ici</a>.</p>
<h2>Conclusion</h2>
<p>Cette série d&rsquo;articles est finie. J&rsquo;espère qu&rsquo;ils vous seront utiles.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adapter une bibliothèque C pour ruby (4)</title>
		<link>https://blog.developpez.com/zik/p9357/ruby/adapter_une_bibliotheque_c_pour_ruby_4</link>
		<comments>https://blog.developpez.com/zik/p9357/ruby/adapter_une_bibliotheque_c_pour_ruby_4#comments</comments>
		<pubDate>Tue, 05 Oct 2010 23:43:54 +0000</pubDate>
		<dc:creator><![CDATA[vinc-mai]]></dc:creator>
				<category><![CDATA[debian-fr]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Ce quatrième billet présente comment obtenir une documentation grâce à rdoc : il suffit de commenter les fichiers sources. Documentation Commenter Pour documenter les méthodes de la classe TagLib::File, il suffit de commenter les différentes fonctions les implémentant. La méthode title permet d&#8217;obtenir le titre d&#8217;une piste. On l&#8217;indique en commentaire juste avant la fonction file_get_title. /*Get track title*/ VALUE file_get_title(VALUE self) Par défaut, les paramètres d&#8217;une méthode sont nommés p1, p2, &#8230;. Pour la [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Ce quatrième billet présente comment obtenir une documentation grâce à <a href="http://rdoc.sourceforge.net/">rdoc</a> : il suffit de commenter les fichiers sources.</p>
<h2>Documentation</h2>
<h3>Commenter</h3>
<p>Pour documenter les méthodes de la classe <b>TagLib::File</b>, il suffit de commenter les différentes fonctions les implémentant.</p>
<p>La méthode <b>title</b> permet d&rsquo;obtenir le titre d&rsquo;une piste. On l&rsquo;indique en commentaire juste avant la fonction <b>file_get_title</b>.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">/*Get track title*/ <br />
VALUE <br />
file_get_title(VALUE self)</div></div>
<p>Par défaut, les paramètres d&rsquo;une méthode sont nommés <b>p1, p2, &#8230;</b>. Pour la méthode <b>title=</b>, on utilise l&rsquo;instruction <b>call-seq:</b> pour afficher le texte <b>title=title</b> (au lieu de <b>title=(p1)</b>).</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">/* <br />
call-seq: title=title <br />
&nbsp;<br />
Set track title to title <br />
&nbsp;<br />
title: a string <br />
*/ <br />
VALUE <br />
file_set_title(VALUE self, VALUE title)</div></div>
<p>La méthode <b>initialize</b> ne devrait jamais être appelée directement depuis un code ruby. On utilise l&rsquo;instruction <b>:nodoc:</b> pour indiquer que la méthode ne doit pas apparaitre dans la documentation.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">/*:nodoc:*/ <br />
VALUE <br />
file_init(VALUE self, VALUE path)</div></div>
<p>J&rsquo;indique que je ne désire pas commenter le module <b>TagLib</b> en plaçant un commentaire vide afin d&rsquo;éviter que rdoc utilise un commentaire non-désiré.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">/* */ <br />
&nbsp; mTagLib=rb_define_module(&quot;TagLib&quot;);</div></div>
<p>Dans le fichier lib/raglib2.rb, j&rsquo;ajoute la directive <b>:main:</b> afin que la page initiale de la documentation pointe sur la classe <b>TagLib::File</b>.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">#:main: TagLib::File <br />
module TagLib</div></div>
<p>Bizarrement, cette directive ne semble pas fonctionner si elle est placée dans le fichier taglib2.c.</p>
<h3>Produire la documentation</h3>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">rdoc --exclude extconf.rb</div></div>
<p>Le fichier doc/index.html est créé.<br />
<img src="http://zik.developpez.com/blog/c_ext/pix/rdoc.png" alt="aperçu de la documentation" title="Documentation" /></p>
<h2>Conclusion</h2>
<p>Rendez-vous pour le dernier billet où j&rsquo;introduirai quelques concepts que je n&rsquo;ai pas utilisé dans le module <b>TagLib</b>.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adapter une bibliothèque C pour ruby (3)</title>
		<link>https://blog.developpez.com/zik/p9348/ruby/adapter_une_bibliotheque_c_pour_ruby_3</link>
		<comments>https://blog.developpez.com/zik/p9348/ruby/adapter_une_bibliotheque_c_pour_ruby_3#comments</comments>
		<pubDate>Mon, 04 Oct 2010 15:47:34 +0000</pubDate>
		<dc:creator><![CDATA[vinc-mai]]></dc:creator>
				<category><![CDATA[debian-fr]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Cet article fait suite au premier et deuxième billets dans lesquels nous avons vu comment créer un objet de la classe TagLib::File. Cet objet utilise les fonctions de la bibliothèque taglib, écrite en C, afin d&#8217;accéder aux tags de fichiers audio. Dans ce billet, nous verrons comment obtenir les valeurs des tags et comment modifier un tag. Jouer avec les tags Accéder au tag La structure tgFileData contient un champ tag qui permettra d&#8217;accéder au [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Cet article fait suite au <a href="http://blog.developpez.com/zik/p9266/ruby/adapter-une-bibliotheque-c-pour-ruby-1/">premier</a> et <a href="http://blog.developpez.com/zik/p9343/ruby/adapter-une-bibliotheque-c-pour-ruby-2/">deuxième</a> billets dans lesquels nous avons vu comment créer un objet de la classe <b>TagLib::File</b>. Cet objet utilise les fonctions de la bibliothèque taglib, écrite en C, afin d&rsquo;accéder aux tags de fichiers audio. Dans ce billet, nous verrons comment obtenir les valeurs des tags et comment modifier un tag.</p>
<p><span id="more-17"></span></p>
<h2>Jouer avec les tags</h2>
<h3>Accéder au tag</h3>
<p>La structure <b>tgFileData</b> contient un champ <b>tag</b> qui permettra d&rsquo;accéder au tag du fichier. Il a été initialisé avec la valeur <b>NULL</b>. La fonction <b>file_tag</b> retourne la valeur de ce champ après l&rsquo;avoir complété au besoin.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">TagLib_Tag * <br />
file_tag(VALUE self) <br />
{ <br />
&nbsp; &nbsp; tgFileData *d; <br />
&nbsp; &nbsp; TagLib_Tag *tgTag; <br />
&nbsp;<br />
&nbsp; &nbsp; Data_Get_Struct(self, tgFileData, d); <br />
&nbsp; &nbsp; if (d-&gt;tag==NULL) <br />
&nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; tgTag=taglib_file_tag(d-&gt;file); <br />
&nbsp; &nbsp; &nbsp; &nbsp; if (tgTag==NULL) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rb_raise(eBadTag, &quot;Bad tag&quot;); <br />
&nbsp; &nbsp; &nbsp; &nbsp; d-&gt;tag=tgTag; <br />
&nbsp; } <br />
&nbsp; &nbsp; return d-&gt;tag; <br />
}</div></div>
<p>La macro <b>Data_Get_Struct</b> permet d&rsquo;accéder à la structure <b>tgFileData</b> de notre objet. Si le champ <b>tag</b> n&rsquo;est pas rempli, on récupère sa valeur grâce à la fonction <b>taglib_file_tag</b> de la bibliothèque taglib. Une exception est levée dans le cas où cette dernière fonction faillirait. La valeur du champ est finalement retournée.</p>
<h3>Obtenir le titre d&rsquo;une piste audio</h3>
<p>Afin d&rsquo;obtenir le titre contenu dans un tag, une méthode <b>title</b> est ajoutée à la classe <b>TagLib::File</b>, dans la fonction <b>Init_taglib2</b>.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">rb_define_method(cFile, &quot;title&quot;, file_get_title, 0);</div></div>
<p>La fonction <b>file_get_title</b> implémente la méthode <b>TagLib::File#title</b></p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">VALUE <br />
file_get_title(VALUE self) <br />
{ <br />
&nbsp; VALUE str; <br />
&nbsp;<br />
&nbsp; str=rb_str_new2(taglib_tag_title(file_tag(self))); <br />
&nbsp; taglib_tag_free_strings; <br />
&nbsp; &nbsp; return str; <br />
}</div></div>
<p>La valeur du titre est obtenu grâce à la fonction <b>taglib_tag_title</b> qui prend la valeur du champ tag de la structure interne <b>tgFileData</b>. La fonction <b>rb_str_new2</b> transforme cette valeur obtenue sous la forme d&rsquo;un pointeur sur chaîne de caractères en un objet ruby de la classe <b>String</b>. La mémoire allouée par taglib pour cette opération est libérée avant de retourner l&rsquo;objet.</p>
<h3>Modifier le titre d&rsquo;une piste audio</h3>
<p>La méthode <b>TagLib::File#title=</b>, prenant un argument, est ajoutée.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">rb_define_method(cFile, &quot;title=&quot;, file_set_title, 1);</div></div>
<p>La fonction<b>file_set_title</b> utilise la bibliothèque taglib pour modifier le tag. Une nouvelle fois, la macro <b>StringValuePtr</b> est utilisée pour convertir une variable du type <b>VALUE</b> vers le type <b>char *</b>. Une fonction implémentant une méthode accessible depuis ruby doit obligatoirement retournée une valeur du type <b>VALUE</b>. J&rsquo;ai choisi ici de retourner la chaîne de caractère passée en argument.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">VALUE <br />
file_set_title(VALUE self, VALUE title) <br />
{ <br />
&nbsp; &nbsp; taglib_tag_set_title(file_tag(self), StringValuePtr(title)); <br />
&nbsp; &nbsp; return title; <br />
}</div></div>
<p><em>Il me semble que traditionnellement les méthodes du type <b>variable=</b> retourne l&rsquo;argument alors que les méthodes du type <b>set_variable</b> retourne l&rsquo;objet. La troisième possibilité étant de retourner <b>nil</b>.</em></p>
<h3>Sauvegarder les modifications</h3>
<p>Après avoir modifié le titre à l&rsquo;aide de la méthode vue au précédent paragraphe, il faut écrire cette modification dans le fichier audio.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">rb_define_method(cFile, &quot;save&quot;, file_save, 0);</div></div>
<p>La méthode <b>TagLib::File#save</b> permet cette écriture. La méthode retourne <b>true</b> si l&rsquo;opération est réussie ou <b>false</b>.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">VALUE <br />
file_save(VALUE self) <br />
{ <br />
&nbsp; &nbsp; tgFileData *data; <br />
&nbsp;<br />
&nbsp; &nbsp; Data_Get_Struct(self, tgFileData, data); <br />
&nbsp; &nbsp; if (taglib_file_save(data-&gt;file)) <br />
&nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; return Qtrue; <br />
&nbsp; } <br />
&nbsp; &nbsp; else <br />
&nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; return Qfalse; <br />
&nbsp; } <br />
}</div></div>
<p>La fonction <b>taglib_file_save</b> réalise l&rsquo;écriture après avoir accédé au champ <b>file</b> de la structure interne de notre objet ruby.</p>
<h3>Tester le code</h3>
<p>Voici le contenu du fichier taglib2.c</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ cat taglib2.c <br />
#include &lt;ruby.h&gt; <br />
#include &lt;taglib/tag_c.h&gt; <br />
&nbsp;<br />
typedef struct <br />
{ <br />
&nbsp; &nbsp; TagLib_File *file; <br />
&nbsp; &nbsp; TagLib_Tag *tag; <br />
&nbsp; &nbsp; const TagLib_AudioProperties *audio; <br />
} tgFileData; <br />
&nbsp;<br />
VALUE mTagLib; <br />
VALUE eBadPath, eBadFile, eBadTag, eBadAudioProperties; <br />
VALUE cFile; <br />
&nbsp;<br />
static void <br />
free_tgFileData(tgFileData *d) <br />
{ <br />
&nbsp; &nbsp; taglib_file_free(d-&gt;file); <br />
&nbsp; &nbsp; free(d); <br />
} <br />
&nbsp;<br />
TagLib_Tag * <br />
file_tag(VALUE self) <br />
{ <br />
&nbsp; &nbsp; tgFileData *d; <br />
&nbsp; &nbsp; TagLib_Tag *tgTag; <br />
&nbsp;<br />
&nbsp; &nbsp; Data_Get_Struct(self, tgFileData, d); <br />
&nbsp; &nbsp; if (d-&gt;tag==NULL) <br />
&nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; tgTag=taglib_file_tag(d-&gt;file); <br />
&nbsp; &nbsp; &nbsp; &nbsp; if (tgTag==NULL) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rb_raise(eBadTag, &quot;Bad tag&quot;); <br />
&nbsp; &nbsp; &nbsp; &nbsp; d-&gt;tag=tgTag; <br />
&nbsp; } <br />
&nbsp; &nbsp; return d-&gt;tag; <br />
} <br />
&nbsp;<br />
VALUE <br />
file_init(VALUE self, VALUE path) <br />
{ <br />
&nbsp; &nbsp; rb_iv_set(self, &quot;@path&quot;, path); <br />
&nbsp; &nbsp; return self; <br />
} <br />
&nbsp;<br />
VALUE <br />
file_new(VALUE self, VALUE path) <br />
{ <br />
&nbsp; &nbsp; TagLib_File *tgFile; <br />
&nbsp; &nbsp; tgFileData *data; <br />
&nbsp; &nbsp; VALUE rbData; <br />
&nbsp; &nbsp; VALUE argv[1]; <br />
&nbsp;<br />
&nbsp; &nbsp; tgFile=taglib_file_new(StringValuePtr(path)); <br />
&nbsp; &nbsp; if (tgFile==NULL) <br />
&nbsp; &nbsp; &nbsp; &nbsp; rb_raise(eBadPath, &quot;Bad path&quot;); <br />
&nbsp;<br />
&nbsp; &nbsp; data=ALLOC(tgFileData); <br />
&nbsp; &nbsp; data-&gt;file=tgFile; <br />
&nbsp; &nbsp; data-&gt;tag=NULL; <br />
&nbsp; &nbsp; data-&gt;audio=NULL; <br />
&nbsp; &nbsp; rbData=Data_Wrap_Struct(cFile, 0, free_tgFileData, data); <br />
&nbsp; &nbsp; argv[0]=path; <br />
&nbsp; &nbsp; rb_obj_call_init(rbData, 1, argv); <br />
&nbsp; &nbsp; return rbData; <br />
} <br />
&nbsp;<br />
VALUE <br />
file_save(VALUE self) <br />
{ <br />
&nbsp; &nbsp; tgFileData *data; <br />
&nbsp;<br />
&nbsp; &nbsp; Data_Get_Struct(self, tgFileData, data); <br />
&nbsp; &nbsp; if (taglib_file_save(data-&gt;file)) <br />
&nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; return Qtrue; <br />
&nbsp; } <br />
&nbsp; &nbsp; else <br />
&nbsp; &nbsp; { <br />
&nbsp; &nbsp; &nbsp; &nbsp; return Qfalse; <br />
&nbsp; } <br />
} <br />
&nbsp;<br />
VALUE <br />
file_get_title(VALUE self) <br />
{ <br />
&nbsp; VALUE str; <br />
&nbsp;<br />
&nbsp; str=rb_str_new2(taglib_tag_title(file_tag(self))); <br />
&nbsp; taglib_tag_free_strings; <br />
&nbsp; &nbsp; return str; <br />
} <br />
&nbsp;<br />
VALUE <br />
file_set_title(VALUE self, VALUE title) <br />
{ <br />
&nbsp; &nbsp; taglib_tag_set_title(file_tag(self), StringValuePtr(title)); <br />
&nbsp; &nbsp; return title; <br />
} <br />
&nbsp;<br />
void <br />
Init_taglib2() <br />
{ <br />
&nbsp; mTagLib=rb_define_module(&quot;TagLib&quot;); <br />
&nbsp;<br />
&nbsp; eBadPath=rb_define_class_under(mTagLib, &quot;BadPath&quot;, rb_eException); <br />
&nbsp; &nbsp; eBadFile=rb_define_class_under(mTagLib, &quot;BadFile&quot;, rb_eException); <br />
&nbsp; &nbsp; eBadTag=rb_define_class_under(mTagLib, &quot;BadTag&quot;, rb_eException); <br />
&nbsp; &nbsp; eBadAudioProperties=rb_define_class_under(mTagLib, &quot;BadAudioProperties&quot;, rb_eException); <br />
&nbsp;<br />
&nbsp; &nbsp; cFile=rb_define_class_under(mTagLib, &quot;File&quot;, rb_cObject); <br />
&nbsp; &nbsp; rb_define_singleton_method(cFile, &quot;new&quot;, file_new, 1); <br />
&nbsp; &nbsp; rb_define_method(cFile, &quot;initialize&quot;, file_init, 1); <br />
&nbsp; &nbsp; rb_define_method(cFile, &quot;save&quot;, file_save, 0); <br />
&nbsp; &nbsp; rb_define_method(cFile, &quot;title&quot;, file_get_title, 0); <br />
&nbsp; &nbsp; rb_define_method(cFile, &quot;title=&quot;, file_set_title, 1); <br />
}</div></div>
<p>Après avoir recompilé, nous pouvons tester les méthodes ajoutées dans cet article.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ make <br />
$ irb <br />
&gt; require './lib/taglib2.rb' <br />
=&gt; true <br />
&gt; t=TagLib::File.new('Musique/01 - Blue Bird.mp3') <br />
=&gt; #&lt;TagLib::File:0xb74ca844&gt; <br />
&gt; t.title <br />
=&gt; &quot;Blue Bird&quot; <br />
&gt; t.title='toto' <br />
=&gt; &quot;toto&quot; <br />
&gt; t.title <br />
=&gt; &quot;toto&quot; <br />
&gt; t.save <br />
=&gt; true</div></div>
<h2>Conclusion</h2>
<p>Nous avons vu comment accéder au titre d&rsquo;une piste audio. Accéder aux autres propriétés (auteur, album, etc) n&rsquo;est pas plus difficile. Je ne développerai pas cet aspect. Les sources du code complet seront cependant mis à votre disposition lors du dernier article. Le prochain article devrait parler de l&rsquo;aspect documentation.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adapter une bibliothèque C pour ruby (2)</title>
		<link>https://blog.developpez.com/zik/p9343/ruby/adapter_une_bibliotheque_c_pour_ruby_2</link>
		<comments>https://blog.developpez.com/zik/p9343/ruby/adapter_une_bibliotheque_c_pour_ruby_2#comments</comments>
		<pubDate>Sun, 03 Oct 2010 14:37:27 +0000</pubDate>
		<dc:creator><![CDATA[vinc-mai]]></dc:creator>
				<category><![CDATA[debian-fr]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Cet article fait suite au premier. Il s&#8217;intéresse à la classe principale qui permettra de manipuler les tags de fichiers audio. Addendum Afin que notre bibliothèque soit correctement liée à taglib lors de la compilation, il faut ajouter la ligne have_library(&#8216;tag_c&#8217;) &#124;&#124; exit(1) au fichier extconf.rb, juste avant d&#8217;invoquer la création du Makefile. Créer un objet appartenant à la classe TagLib::File Ajouter une classe File Après avoir déclaré une nouvelle variable de type VALUE (cFile), [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Cet article fait suite au <a href="http://blog.developpez.com/zik/p9266/ruby/adapter-une-bibliotheque-c-pour-ruby-1/">premier</a>. Il s&rsquo;intéresse à la classe principale qui permettra de manipuler les tags de fichiers audio.</p>
<p><span id="more-16"></span></p>
<h2>Addendum</h2>
<p>Afin que notre bibliothèque soit correctement liée à taglib lors de la compilation, il faut ajouter la ligne <b>have_library(&lsquo;tag_c&rsquo;) || exit(1)</b> au fichier <b>extconf.rb</b>, juste avant d&rsquo;invoquer la création du <b>Makefile</b>.</p>
<h2>Créer un objet appartenant à la classe <b>TagLib::File</b></h2>
<h3>Ajouter une classe <b>File</b></h3>
<p>Après avoir déclaré une nouvelle variable de type VALUE (<b>cFile</b>), je définis une nouvelle classe nommée <b>File</b> appartenant au module <b>TagLib</b>. Elle hérite de la classe <b>Objet</b> (classe mère de toutes les classes en ruby).</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ cat taglib2.c <br />
#include &lt;ruby.h&gt; <br />
#include &lt;taglib/tag_c.h&gt; <br />
&nbsp;<br />
VALUE mTagLib; <br />
VALUE eBadPath, eBadFile, eBadTag, eBadAudioProperties; <br />
VALUE cFile; <br />
&nbsp;<br />
void <br />
Init_taglib2() <br />
{ <br />
&nbsp; mTagLib=rb_define_module(&quot;TagLib&quot;); <br />
&nbsp;<br />
&nbsp; eBadPath=rb_define_class_under(mTagLib, &quot;BadPath&quot;, rb_eException); <br />
&nbsp; &nbsp; eBadFile=rb_define_class_under(mTagLib, &quot;BadFile&quot;, rb_eException); <br />
&nbsp; &nbsp; eBadTag=rb_define_class_under(mTagLib, &quot;BadTag&quot;, rb_eException); <br />
&nbsp; &nbsp; eBadAudioProperties=rb_define_class_under(mTagLib, &quot;BadAudioProperties&quot;, rb_eException); <br />
&nbsp;<br />
&nbsp; &nbsp; cFile=rb_define_class_under(mTagLib, &quot;File&quot;, rb_cObject); <br />
}</div></div>
<p>Après avoir recompilé notre bibliothèque, je peux créer un objet de type <b>TagLib::File</b>, cette classe ayant héritée de la méthode <b>Objet.new</b>.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ make distclean <br />
$ ruby extconf.rb <br />
$ make <br />
$ irb <br />
&gt; require './lib/taglib2.rb' <br />
&gt; TagLib::File.superclass <br />
=&gt; Object <br />
&gt; TagLib::File.new <br />
=&gt; #&lt;TagLib::File:0xb75145e8&gt;</div></div>
<h3>Redéfinir la méthode new</h3>
<p>Dans la fonction <b>Init_taglib2</b>, je redéfinis la méthode de classe <b>new</b> (et non une méthode d&rsquo;instance). C&rsquo;est pourquoi j&rsquo;utilise <b>rb_define_singleton_method</b> et non <b>rb_define_method</b>. Cette fonction prend quatre arguments : l&rsquo;object pour lequel la méthode va &#7871;tre (re)défini, le nom de la méthode, la fonction écrite en C à appeler, le nombre d&rsquo;aguments passés à la fonction.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">rb_define_singleton_method(cFile, &quot;new&quot;, file_new, 1);</div></div>
<p>Voici la fonction <b>file_new</b> qui redéfinit <b>TagLib::File.new</b>.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">typedef struct <br />
{ <br />
&nbsp; &nbsp; TagLib_File *file; <br />
&nbsp; &nbsp; TagLib_Tag *tag; <br />
&nbsp; &nbsp; const TagLib_AudioProperties *audio; <br />
} tgFileData; <br />
&nbsp;<br />
VALUE <br />
file_new(VALUE self, VALUE path) <br />
{ <br />
&nbsp; &nbsp; TagLib_File *tgFile; <br />
&nbsp; &nbsp; tgFileData *data; <br />
&nbsp; &nbsp; VALUE rbData; <br />
&nbsp; &nbsp; VALUE argv[1]; <br />
&nbsp;<br />
&nbsp; &nbsp; tgFile=taglib_file_new(StringValuePtr(path)); <br />
&nbsp; &nbsp; if (tgFile==NULL) <br />
&nbsp; &nbsp; &nbsp; &nbsp; rb_raise(eBadPath, &quot;Bad path&quot;); <br />
&nbsp;<br />
&nbsp; &nbsp; data=ALLOC(tgFileData); <br />
&nbsp; &nbsp; data-&gt;file=tgFile; <br />
&nbsp; &nbsp; data-&gt;tag=NULL; <br />
&nbsp; &nbsp; data-&gt;audio=NULL; <br />
&nbsp; &nbsp; rbData=Data_Wrap_Struct(cFile, 0, free_tgFileData, data); <br />
&nbsp; &nbsp; argv[0]=path; <br />
&nbsp; &nbsp; rb_obj_call_init(rbData, 1, argv); <br />
&nbsp; &nbsp; return rbData; <br />
}</div></div>
<p>La méthode <b>new</b> est appelée avec un seul argument qui est une chaîne de caractère ruby représentant un chemin vers un fichier audio. Cependant, la function <b>file_new</b> possède un argument supplémentaire : le premier qui représente l&rsquo;objet auquel s&rsquo;applique la méthode.<br />
La fonction <b>taglib_file_new</b> permet de créer une structure qui représente un fichier audio pour la bibliothèque taglib. Elle requière, comme argument, un pointeur sur une chaîne de caractère C obtenu grâce à la macro <b>StringValuePtr</b>.<br />
La variable <b>data</b> est une structure qui représentera un objet de type <b>TagLib::File</b> au niveau du langage C. Elle est composée de trois champs représentant le fichier audio (<b>file</b>), le tag associé au fichier (<b>tag</b>) et les propriétés audio du fichier (<b>audio</b>). Après avoir alloué la mémoire nécéssaire (grâce à la macro <b>ALLOC</b>) et initialiser ses différents champs, cette structure est transformée en object ruby grâce à l&rsquo;aide de la macro <b>Data_Wrap_Struct</b>. Cet object <b>rbData</b> appartient à la classe <b>TagLib::File</b> (représenté par la variable <b>cFile</b>). Lorsque l&rsquo;objet est détruit, la fonction <b>free_tgFileData</b> est appelée.<br />
Enfin, l&rsquo;objet est initialisé (<b>rb_obj_call_init</b>).</p>
<h3>Écrire la méthode initialize</h3>
<p>La méthode <b>new</b> appelle la méthode <b>initialize</b> qui, comme son nom l&rsquo;indique, s&rsquo;occupe d&rsquo;initialiser l&rsquo;objet, en particulier ses variables d&rsquo;instance.<br />
Cette dernière méthode est déclarée  dans la fonction <b>Init_taglib2</b>.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">rb_define_method(cFile, &quot;initialize&quot;, file_init, 1);</div></div>
<p>Ici, la méthode <b>initialize</b> se borne à valoriser la variable d&rsquo;instance <b>@path</b>.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">VALUE <br />
file_init(VALUE self, VALUE path) <br />
{ <br />
&nbsp; &nbsp; rb_iv_set(self, &quot;@path&quot;, path); <br />
&nbsp; &nbsp; return self; <br />
}</div></div>
<h3>Libérer la mémoire</h3>
<p>Lorsque le ramasse-miettes de ruby détruit un object de type <b>TagLib::File</b>, il utilise la fonction indiquée lors de l&rsquo;appel à la macro <b>Data_Wrap_Struct</b>, pour libérer la mémoire allouée à cet objet.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">static void <br />
free_tgFileData(tgFileData *d) <br />
{ <br />
&nbsp; &nbsp; taglib_file_free(d-&gt;file); <br />
&nbsp; &nbsp; free(d); <br />
}</div></div>
<h3>Code</h3>
<p>Voici l&rsquo;ensemble du code :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ cat extconf.rb <br />
require 'mkmf' <br />
&nbsp;<br />
have_header('ruby.h') || exit(1) <br />
have_header('taglib/tag_c.h') || exit(1) <br />
have_library('tag_c') || exit(1) <br />
&nbsp;<br />
create_makefile(&quot;taglib2&quot;)</div></div>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ cat lib/taglib2.rb <br />
require &quot;taglib2.so&quot; <br />
&nbsp;<br />
module TagLib <br />
VERSION=[0, 0, 1] <br />
end</div></div>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ cat taglib2.c <br />
#include &lt;ruby.h&gt; <br />
#include &lt;taglib/tag_c.h&gt; <br />
&nbsp;<br />
typedef struct <br />
{ <br />
&nbsp; &nbsp; TagLib_File *file; <br />
&nbsp; &nbsp; TagLib_Tag *tag; <br />
&nbsp; &nbsp; const TagLib_AudioProperties *audio; <br />
} tgFileData; <br />
&nbsp;<br />
VALUE mTagLib; <br />
VALUE eBadPath, eBadFile, eBadTag, eBadAudioProperties; <br />
VALUE cFile; <br />
&nbsp;<br />
static void <br />
free_tgFileData(tgFileData *d) <br />
{ <br />
&nbsp; &nbsp; taglib_file_free(d-&gt;file); <br />
&nbsp; &nbsp; free(d); <br />
} <br />
VALUE <br />
file_init(VALUE self, VALUE path) <br />
{ <br />
&nbsp; &nbsp; rb_iv_set(self, &quot;@path&quot;, path); <br />
&nbsp; &nbsp; return self; <br />
} <br />
&nbsp;<br />
VALUE <br />
file_new(VALUE self, VALUE path) <br />
{ <br />
&nbsp; &nbsp; TagLib_File *tgFile; <br />
&nbsp; &nbsp; tgFileData *data; <br />
&nbsp; &nbsp; VALUE rbData; <br />
&nbsp; &nbsp; VALUE argv[1]; <br />
&nbsp;<br />
&nbsp; &nbsp; tgFile=taglib_file_new(StringValuePtr(path)); <br />
&nbsp; &nbsp; if (tgFile==NULL) <br />
&nbsp; &nbsp; &nbsp; &nbsp; rb_raise(eBadPath, &quot;Bad path&quot;); <br />
&nbsp;<br />
&nbsp; &nbsp; data=ALLOC(tgFileData); <br />
&nbsp; &nbsp; data-&gt;file=tgFile; <br />
&nbsp; &nbsp; data-&gt;tag=NULL; <br />
&nbsp; &nbsp; data-&gt;audio=NULL; <br />
&nbsp; &nbsp; rbData=Data_Wrap_Struct(cFile, 0, free_tgFileData, data); <br />
&nbsp; &nbsp; argv[0]=path; <br />
&nbsp; &nbsp; rb_obj_call_init(rbData, 1, argv); <br />
&nbsp; &nbsp; return rbData; <br />
} <br />
&nbsp;<br />
void <br />
Init_taglib2() <br />
{ <br />
&nbsp; mTagLib=rb_define_module(&quot;TagLib&quot;); <br />
&nbsp;<br />
&nbsp; eBadPath=rb_define_class_under(mTagLib, &quot;BadPath&quot;, rb_eException); <br />
&nbsp; &nbsp; eBadFile=rb_define_class_under(mTagLib, &quot;BadFile&quot;, rb_eException); <br />
&nbsp; &nbsp; eBadTag=rb_define_class_under(mTagLib, &quot;BadTag&quot;, rb_eException); <br />
&nbsp; &nbsp; eBadAudioProperties=rb_define_class_under(mTagLib, &quot;BadAudioProperties&quot;, rb_eException); <br />
&nbsp;<br />
&nbsp; &nbsp; cFile=rb_define_class_under(mTagLib, &quot;File&quot;, rb_cObject); <br />
&nbsp; &nbsp; rb_define_singleton_method(cFile, &quot;new&quot;, file_new, 1); <br />
&nbsp; &nbsp; rb_define_method(cFile, &quot;initialize&quot;, file_init, 1); <br />
}</div></div>
<h3>Tester le code</h3>
<p>Après une recompilation, on vérifie que la méthode <b>TagLib::File.new</b> est correctement appelée depuis l&rsquo;interpréteur irb.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ make <br />
$ irb <br />
&gt; require './lib/taglib2.rb' <br />
=&gt; true <br />
&gt; t=TagLib::File.new('Musique/01 - Blue Bird.mp3') <br />
=&gt; #&lt;TagLib::File:0xb74c29a0&gt; <br />
&gt; t.instance_variable_get(&quot;@path&quot;) <br />
=&gt; &quot;Musique/01 - Blue Bird.mp3&quot;</div></div>
<h2>Conclusion</h2>
<p>Lors de ce deuxième billet, nous avons interfacé une structure C avec un objet ruby, représentant un fichier audio. Dans le prochain billet, nous écrirons les méthodes qui permettent d&rsquo;accéder au tag de ce fichier.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bonjour planète</title>
		<link>https://blog.developpez.com/zik/p9318/debian-fr/bonjour_planete</link>
		<comments>https://blog.developpez.com/zik/p9318/debian-fr/bonjour_planete#comments</comments>
		<pubDate>Fri, 24 Sep 2010 08:01:47 +0000</pubDate>
		<dc:creator><![CDATA[vinc-mai]]></dc:creator>
				<category><![CDATA[debian-fr]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Suite à ma première contribution directe au projet debian (cf : ci-dessous), j&#8217;écris ce billet pour présenter mon expérience avec linux. Je précise que je ne suis pas informaticien de formation. À la découverte de linux Suite à quelques utilisations sporadiques de différentes distributions linux, j&#8217;ai réellement découvert linux en installant ubuntu 5.10. Après avoir réglé quelques difficultés, je trouve mes marques et retrouve certains logiciels que j&#8217;utilisais sous windows. Un seul logiciel me manque [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Suite à ma première contribution directe au projet debian (cf : ci-dessous), j&rsquo;écris ce billet pour présenter mon expérience avec linux. Je précise que je ne suis pas informaticien de formation.</p>
<h2>À la découverte de linux</h2>
<p>Suite à quelques utilisations sporadiques de différentes distributions linux, j&rsquo;ai réellement découvert linux en installant ubuntu 5.10. Après avoir réglé quelques difficultés, je trouve mes marques et retrouve certains logiciels que j&rsquo;utilisais sous windows. Un seul logiciel me manque vraiment, il s&rsquo;agit de <a href="http://dekibulle.free.fr/">DéKiBulle</a> un lecteur audio que j&rsquo;apprécie particulièrement.</p>
<h2>À la découverte de ruby</h2>
<p>Plus pour m&rsquo;amuser que pour autres choses, en 2007, je commence à développer un petit script, en bash, nommé ZiK qui me permet de lire mes fichiers audio. Puis je décide de développer une interface graphique et un lecteur audio digne de ce nom dans l&rsquo;idée d&rsquo;apprendre un langage de programmation. Après avoir hésité entre ruby et python, j&rsquo;opte pour ruby. Si j&rsquo;avais su que python est livré en standard dans la plupart des distributions, mon choix aurait peut-être été différent. Cependant, je ne regrette pas mon choix, je trouve ruby plus sexy (avis totalement orienté par mon expérience).</p>
<h2>À la (re)découverte des paquets debian</h2>
<p>J&rsquo;ai découvert les paquets debian côté « fabricant » lorsque j&rsquo;ai voulu distribuer ZiK sous la forme d&rsquo;un paquet debian.<br />
J&rsquo;ai procédé en plusieurs étapes.<br />
J&rsquo;ai tout d&rsquo;abord, tout simplement, invoquer <b>dpkg-deb &#8211;build</b> sur une arborescence locale imageant une installation de ZiK en prenant soin d&rsquo;ajouter un dossier <b>DEBIAN</b> contenant les fichiers <b>control</b> et <b>changelog</b>.<br />
J&rsquo;ai ensuite écrit un fichier <b>rules</b> afin de pouvoir publier un paquet sur mon ppa (<b>debuild</b> et <b>pbuilder</b> sont devenus alors très utiles). La qualité de paquets disponibles sur ce dernier laissent à désirer.<br />
La troisième étape implique la création de paquets plus propres qui seront, si possible, intégrés à debian.</p>
<h2>Contribuer à debian</h2>
<p>Afin de pouvoir définir des raccourcis clavier globaux pour mon application ZiK, je développe une bibliothèque nommée rghk (ruby global hotkeys). La construction de son paquet debian étant relativement aisé, je me suis proposé pour inclure cette bibliothèque. Elle est maintenant disponible pour debian unstable (ainsi que sous ubuntu 10.10) sous le nom <b>libglobalhotkeys-ruby</b>. Elle ne devrait cependant pas être incluse dans squeeze car son arrivée dans les dépôts à précéder le gel seulement de quelques heures.<br />
Je remercie Lucas Nussbaum de l&rsquo;équipe <a href="http://pkg-ruby-extras.alioth.debian.org/">pkg-ruby-extra</a> pour son aide lors du processus d&rsquo;inclusion.<br />
Ayant réussi mon galon d&rsquo;essai, ZiK devrait prochainement rejoindre debian (en version 0.15 ou 0.16).</p>
<h2>Mes codes</h2>
<h3>rghk</h3>
<p><a href="http://zik.rubyforge.org/rghk/">rghk</a> permet de définir des raccoucrcis clavier globaux (actifs même si l&rsquo;applications est en arrière plan).<br />
Le code suivant permet d&rsquo;afficher <b>Binded</b> lorsque les touches <b>control</b> et <b>a</b> sont enfoncées. Un exemple plus détaillé est disponible avec le code source.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;require 'globalhotkeys'#Since 0.2.0 <br />
&nbsp;#require 'rghk'#for older version <br />
&nbsp;kb=GlobalHotKeys::KeyBinder.new <br />
&nbsp;kb.bind(GlobalHotKeys::KeyVal.from_name('a'), &nbsp;GlobalHotKeys::Modifier::CONTROL_MASK){puts 'Binded'} <br />
&nbsp;#GlobalHotKeys::KeyVal.from_name function is implemented since 0.2.0 <br />
&nbsp;kb.unbind</div></div>
<p>La dernière version de rghk, pas encore disponible sous debian, apporte des changements importants :<br />
l&rsquo;appel à <b>require</b> a été modifié,<br />
la possibilité d&rsquo;obtenir la « valeur d&rsquo;une touche clavier » depuis une chaîne de caractère.</p>
<h3>ZiK</h3>
<p>Si vous voulez tester le lecteur audio nommé <a href="http://zik.developpez.com/">ZiK</a>, un <a href="http://projets.developpez.com/projects/zik/files">paquet debian</a> est disponible. Les instructions pour l&rsquo;installation du paquet sont disponibles sur le <a href="http://projets.developpez.com/projects/zik/wiki/Installation_(deb)">wiki</a>.<br />
Pour les utilisateurs d&rsquo;Ubuntu un <a href="https://launchpad.net/~vinc-mai/+archive/zik">ppa</a> permet une installation aisée de ZiK sous ubuntu. L&rsquo;installation est détaillée sur le <a href="http://projets.developpez.com/projects/zik/wiki/Ubuntu">wiki</a>.<br />
N&rsquo;hésitez pas à faire part de vos impressions.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Contribuer au graphisme de ZiK</title>
		<link>https://blog.developpez.com/zik/p9209/zik/contribuer_au_graphisme_de_zik_1</link>
		<comments>https://blog.developpez.com/zik/p9209/zik/contribuer_au_graphisme_de_zik_1#comments</comments>
		<pubDate>Mon, 16 Aug 2010 18:42:38 +0000</pubDate>
		<dc:creator><![CDATA[vinc-mai]]></dc:creator>
				<category><![CDATA[debian-fr]]></category>
		<category><![CDATA[ZiK]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Bonjour. ZiK utilise intensivement le thème de l&#8217;utilisateur. Seules quelques images sont fournies directement par le lecteur audio. J&#8217;aimerai personnaliser ces dernières. Cependant, je n&#8217;ai pas le talent nécessaire pour créer ces images. Je lance donc un appel à contribution. Pour l&#8217;instant six images sont concernées. On peut les apercevoir au niveau du bouton qui permet de changer de vue. Il faudrait donc des images représentant : la vue navigateur, la vue liste de lecture, [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Bonjour.</p>
<p>ZiK utilise intensivement le thème de l&rsquo;utilisateur. Seules quelques images sont fournies directement par le lecteur audio.<br />
J&rsquo;aimerai personnaliser ces dernières. Cependant, je n&rsquo;ai pas le talent nécessaire pour créer ces images. Je lance donc un appel à contribution.</p>
<p>Pour l&rsquo;instant six images sont concernées. On peut les apercevoir au niveau du bouton qui permet de changer de vue. Il faudrait donc des images représentant :<br />
la vue navigateur,<br />
la vue liste de lecture,<br />
la vue générale (navigateur et liste de lecture),<br />
la vue compacte (navigateur et liste de lecture cachés),<br />
la vue cd,<br />
la vue radio.</p>
<p>Par la suite, trois autres images devraient être nécessaires. Elles représenteront :<br />
un dossier,<br />
un fichier audio,<br />
une liste de lecture (fichiers m3u, pls ou xspf&#8230;).<br />
Elles seront visibles depuis la partie navigateur.</p>
<p>J&rsquo;aimerai que les images soient au format svg et sous une licence (Creative Commons ?) permettant leur distribution avec les sources de ZiK ainsi qu&rsquo;une intégration facile à des distributions linux (ex : debian).</p>
<p>N&rsquo;hésitez pas à me contacter si vous avez des questions où si vous êtes intéressés pour contribuer à ZiK.<br />
Je remercie d&rsquo;avance toute personne me contactant à ce sujet.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Debian</title>
		<link>https://blog.developpez.com/zik/p9184/zik/debian_1</link>
		<comments>https://blog.developpez.com/zik/p9184/zik/debian_1#comments</comments>
		<pubDate>Fri, 06 Aug 2010 16:46:00 +0000</pubDate>
		<dc:creator><![CDATA[vinc-mai]]></dc:creator>
				<category><![CDATA[debian-fr]]></category>
		<category><![CDATA[rghk]]></category>
		<category><![CDATA[ZiK]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Afin de pouvoir définir des raccourcis clavier globaux, ZiK utilise rghk. rghk est une bibliothèque ruby qui permet de définir raccourcis clavier pour une application graphique fonctionnant même si la fenêtre de l&#8217;application n&#8217;est pas active. rghk est maintenant intégré au projet debian. Le paquet source se nomme libglobalhotkeys-ruby. Je ne pose la question si je dois renommer rghk (rglobalhotkeys, ruby-globalhotkeys ?). Suite à cette première contribution à debian, je compte inclure ZiK (en version [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Afin de pouvoir définir des raccourcis clavier globaux, <a href="http://zik.developpez.com/">ZiK</a> utilise <a href="http://zik.rubyforge.org/rghk/">rghk</a>. rghk est une bibliothèque ruby qui permet de définir raccourcis clavier pour une application graphique fonctionnant même si la fenêtre de l&rsquo;application n&rsquo;est pas active.<br />
rghk est maintenant intégré au projet debian. Le paquet source se nomme libglobalhotkeys-ruby. Je ne pose la question si je dois renommer rghk (rglobalhotkeys, ruby-globalhotkeys ?).<br />
Suite à cette première contribution à debian, je compte inclure ZiK (en version 0.15 ?).</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
