XPCOM
Utilisation des composants
Utilisation des composants en JavaScript
Nous avons créé deux composants (l'un en C++, l'autre en JavaScript) implantant la même interface. Il s'agit maintenant d'utiliser ces composants.
J'ai opté pour l'utilisation des composants depuis un script écrit en JavaScript. Cela offre le mérite d'être simple à mettre en place. Nous allons en effet créer un script qui sera interprété en lançant xpcshell
, qui est un shell JavaScript.
L'utilisation d'un composant passe par trois étapes :
- La recherche de la classe grâce à son Contract ID (dans le tableau
Components.classes
). - La création d'une nouvelle instance (appel de la méthode
createInstance
). - L'appel de la méthode
QueryInterface
pour spécifier l'interface à utiliser.
L'exemple suivant crée une instance du composant JavaScript, puis appelle la méthode display
de celui-ci. La même opération est ensuite réaliser pour le composant C++.
Voici le code correspondant :
// RECUPERE L'UUID DE L'INTERFACE
var iface = Components.interfaces.nsIPlop;
//////////////////////////////////////////////////////////////////// JAVASCRIPT
// RECUPERE LA CLASSE GRACE AU 'CONTRACT ID'
var jsClass = Components.classes["@seigneurin.com/Plop_js;1"];
// INSTANCIE LE COMPOSANT JAVASCRIPT
var jsComponent = jsClass.createInstance(iface);
// DEMANDE L'INTERFACE
jsComponent = jsComponent.QueryInterface(iface);
// APPELLE UNE METHODE
jsComponent.display("hello Mr JS !");
/////////////////////////////////////////////////////////////////////////// C++
// RECUPERE LA CLASSE GRACE AU 'CONTRACT ID'
var cppClass = Components.classes["@seigneurin.com/Plop_cpp;1"];
// INSTANCIE LE COMPOSANT JAVASCRIPT
var cppComponent = cppClass.createInstance(iface);
// DEMANDE L'INTERFACE
cppComponent = cppComponent.QueryInterface(iface);
// APPELLE UNE METHODE
cppComponent.display("hello Mr C++ !");
Lancement du test
Le script défini plus haut est placé dans le fichier MOZILLA/dist/bin/plop_test.js
. Il peut être interprété en lançant la commande suivante dans le répertoire MOZILLA/dist/bin/
:
$ ./xpcshell plop_test.js
Voici un exemple de lancement :
$ ./xpcshell plop_test.js
Warning: MOZILLA_FIVE_HOME not set.
No Persistent Registry Found.
Type Manifest File: /home/alexis/mozilla/dist/bin/components/xpti.dat
nsNativeComponentLoader: autoregistering begins.
[...]
*** Registering plopModule components (all right -- a generic module!)
nsNativeComponentLoader: autoregistering succeeded
[...]
----- Initialisation du module JavaSript
[...]
nsNativeComponentLoader: autoregistering succeeded
[...]
----- Composant JavaSript: Appel de 'createInstance'
----- Composant JavaSript: Appel de 'QueryInterface'
----- Composant JavaSript: Appel de 'QueryInterface'
----- Composant JavaSript: Appel de 'QueryInterface'
----- Composant JavaSript: Appel de 'display' ---> 'hello Mr JS !'
----- Composant C++: Construction
----- Composant C++: Appel de 'display' ---> 'hello Mr C++ !'
----- Composant C++: Destruction
[...]
*** Unloading sample JS components
nsStringStats
=> mAllocCount: 4809
=> mReallocCount: 1745
=> mFreeCount: 4809
=> mShareCount: 6611
=> mAdoptCount: 1717
=> mAdoptFreeCount: 1716
On peut remarquer les étapes suivantes :
- Mozilla ne trouve pas le fichier
/home/alexis/mozilla/dist/bin/components/xpti.dat
et lance donc la recherche et l'enregistrement des composants (autoregistering begins
) ; - Le module C++ est chargé (
Registering plopModule components
) ; - Le module JavaScript est chargé (
Initialisation du module JavaSript
) ; - Le script
plop_test.js
commence à être interprété ; - Le composant JavaScript est créé et utilisé (appels des méthodes
createInstance
,QueryInterface
etdisplay
) ; - Le composant C++ est créé et utilisé ;
- Les composants sont libérés (le compteur de référence du composant C++ tombe notamment à zéro, ce qui a pour effet d'engendrer sa destruction :
Composant C++: Destruction
), puis Mozilla s'arrête ;