Voir aussi le guide utilisateur JSAPI. Il possède de meilleurs et plus nombreux exemples de code!
Un Tutoriel Couvrant l'Essentiel
Exemple d'intégration dans une application
Le code suivant est une simple application montrant comment intégrer SpiderMonkey et exécuter un script Javascript simple. Voir les instructions concernant la compilation et l'exécution en dessous du code.
/* * Uniquement sur Windows, il s'agit d'un fix pour le bug 661663. */ #ifdef _MSC_VER # define XP_WIN #endif /* Inclusion du header JSAPI afin d'accéder à SpiderMonkey. */ #include "jsapi.h" /* La classe de l'objet global. */ static JSClass global_class = { "global", JSCLASS_GLOBAL_FLAGS, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, JSCLASS_NO_OPTIONAL_MEMBERS }; /* Callback du rapporteur d'erreurs. */ void reportError(JSContext *cx, const char *message, JSErrorReport *report) { fprintf(stderr, "%s:%u:%s\n", report->filename ? report->filename : "<no filename=\"filename\">", (unsigned int) report->lineno, message); } int main(int argc, const char *argv[]) { /* Variables JSAPI. */ JSRuntime *rt; JSContext *cx; JSObject *global; /* Créer un runtime JS. Il faut toujours un runtime par processus. */ rt = JS_NewRuntime(8 * 1024 * 1024); if (rt == NULL) return 1; /* * Créée un contexte. Il faut toujours un contexte par thread. * Notez que ce programme n'est pas multi-threadé. */ cx = JS_NewContext(rt, 8192); if (cx == NULL) return 1; JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT); JS_SetVersion(cx, JSVERSION_LATEST); JS_SetErrorReporter(cx, reportError); /* * Créée l'objet global dans un nouveau compartiment. * Il faut toujours un objet global par contexte. */ global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL); if (global == NULL) return 1; /* * On peuple l'objet global avec les fonctions et les objets * Javascript standard, tels que Object, Array ou Date. */ if (!JS_InitStandardClasses(cx, global)) return 1; /* Le code de votre application est ici. Ceci inclue la création de * vos propres objets Javascript ou l'exécution de scripts via JSAPI. * * L'exemple suivant créée un script Javascript littéral, * l'évalue, et affiche le résultat dans stdout. * * Par convention les erreurs sont stockées dans la variable JSBool ok. */ const char *script = "'Hello ' + 'World!'"; jsval rval; JSString *str; JSBool ok; const char *filename = "noname"; uintN lineno = 0; ok = JS_EvaluateScript(cx, global, script, strlen(script), filename, lineno, &rval); if (rval == JS_NULL | rval == JS_FALSE) return 1; str = JS_ValueToString(cx, rval); printf("%s\n", JS_EncodeString(cx, str)); /* Fin de votre code d'application */ /* Nettoyage et fermeture de SpiderMonkey. */ JS_DestroyContext(cx); JS_DestroyRuntime(rt); JS_ShutDown(); return 0; }
L'exemple Hello World mis à jour pour SpiderMonkey24:
#include "jsapi.h"/* Classe de l'objet global. */
static JSClass global_class = {
"global",
JSCLASS_GLOBAL_FLAGS,
JS_PropertyStub,
JS_DeletePropertyStub,
JS_PropertyStub,
JS_StrictPropertyStub,
JS_EnumerateStub,
JS_ResolveStub,
JS_ConvertStub
};
int main(int argc, const char *argv[])
{
JS_Init();
JSRuntime *rt = JS_NewRuntime(8L * 1024 * 1024, JS_NO_HELPER_THREADS);
if (!rt)
return 1;
JSContext *cx = JS_NewContext(rt, 8192);
if (!cx)
return 1;
JS::RootedObject global(cx, JS_NewGlobalObject(cx, &global_class, nullptr, JS::DontFireOnNewGlobalHook));
if (!global)
return 1;
JS::Value rval;
bool ok;
{
JSAutoCompartment ac(cx, *global);
JS_InitStandardClasses(cx, *global);
const char *script = "'hello'+'world, it is '+new Date()";
const char *filename = "noname";
int lineno = 0;
ok = JS_EvaluateScript(cx, *global, script, strlen(script), filename, lineno, &rval);if (rval.isNull() | rval.isFalse() )
return 1;
}
JSString *str = rval.toString();
printf("%s\n", JS_EncodeString(cx, str));
JS_DestroyContext(cx);
JS_DestroyRuntime(rt);
JS_ShutDown();
return 0;
}
Compiler et exécuter l'exemple Hello World
g++ -I<objdir>/dist/include -L<objdir>/dist/bin -lmozjs185 helloworld.cpp -O helloworld
cl helloworld.cpp -link dist/lib/mozjs185-1.0.lib
Hello World!
- Assurez-vous que l'ordinateur sur lequel vous effectuez la compilation remplit les prérequis pour compiler SpiderMonkey: Linux, Windows, Mac OS X, autres. Pour Windows, les étapes suivantes permettent de s'assurer que le package MozillaBuild est bien installé.
- Récupérez le code source de SpiderMonkey. Vous pouvez télécharger un archive contenant les sources ou utiliser Mercurial (hg) pour cloner le dépôt SpiderMonkey. Sur Windows, n'installez pas les sources de SpiderMonkey sous le dossier racine MSYS (qui est en général
c:\mozilla-build\msys
). Utilisez plutôt par exemplec:\js-1.8.5
. - Compilez SpiderMonkey en utilisant les instructions se trouvant dans Documentation de la compilation de SpiderMonkey. Par défaut une bibliothèque partagée de SpiderMonkey sera compilée que vous pourrez lier à votre application dans une prochaine étape.
- Copiez l'exemple de code plus haut dans un éditeur de texte et enregistrer le fichier en tant que
helloworld.cpp
dans le dossier de SpiderMonkeyjs\src
. Pour copier le code sans les numéros de lignes, placez la souris au dessus de l'exemple près du haut et attendez l'apparition des boutons. Cliquez ensuite sur le bouton voir source, et copiez le code depuis la fenêtre qui apparaît. - Compilez l'application HelloWorld and liez avec la bibliothèque SpiderMonkey.
- cl helloworld.cpp -link dist/lib/mozjs185-1.0.lib
- Exécutez le programme
helloworld
à l'aide de la ligne de commande:
./helloworld
Appeler des fonctions C depuis Javascript
Mettons que la fonction C est nommée doit
et demande au moins deux paramètres lors de l'appel (si l'appelant en fournit moins, le moteur JS doit s'assurer que undefined est passé pour ceux manquants) :
#define DOIT_MINARGS 2
static JSBool
doit(JSContext *cx, unsigned argc, jsval *vp)
{
jsval *argv = JS_ARGV(cx, vp);
/*
* Cherche dans argv les paramètres, et assigne *rval pour
* retourner une valeur à l'appelant.
*/
...
}
Pour faire le lien avec JS, vous pouvez écrire :
ok = JS_DefineFunction(cx, global, "doit", doit, DOIT_MINARGS, 0);
Si vous avez plusieurs fonction natives à définir, vous pouvez les mettre dans un tableau :
static JSFunctionSpec my_functions[] = { {"doit", doit, DOIT_MINARGS, 0, 0}, etc... {0,0,0,0,0}, };
(la spécification de fonction comportant uniquement des zéros délimite la fin du tableau) et effectuer :
ok = JS_DefineFunctions(cx, global, my_functions);
Appeler des fonctions Javascript depuis C
Considérons qu'un évènement de clic concerne l'élément d'interface utilisateur le plus à l'avant ou qui a le focus à une position donnée (x, y) :
JSObject *target, *event; jsval argv[1], rval; /* * On trouve la cible de l'évènement et créée un object d'évènement * représentant le clic. * On passe cx à NewEventObject pour que JS_NewObject puisse être appelé. */ target = FindEventTargetAt(cx, global, x, y); event = NewEventObject(cx, "click", x, y); argv[0] = OBJECT_TO_JSVAL(event); /* Pour émuler le DOM, vous pouvez aussi essayer "onclick". */ ok = JS_CallFunctionName(cx, target, "onClick", 1, argv, &rval); /* On teste rval pour voir si l'évènement doit être annulé. */ if (JSVAL_IS_BOOLEAN(rval) && !JSVAL_TO_BOOLEAN(rval)) CancelEvent(event);
Une fois de plus, les tests d'erreurs ont été omis (tel que tester !ok
après l'appel), et quelques comportements dans la gestion des évènements C pour annuler un évènement si le handler retourne false ont été simulés.
Informations sur le document original
- Auteur : Brendan Eich
- Dernière mise à jour : 21 Février 2000