La documentazione di v8 di Google descrive come aggiungere una funzione globale a un contesto JavaScript. Siamo in grado di implementare una funzione printf simile abbastanza facilmente usando la nuova funzione di lambda da C++ 11:v8 :: FunctionTemplate che fa riferimento a una variabile non globale
Handle<ObjectTemplate> global = ObjectTemplate::New();
global->Set(String::New("print"), FunctionTemplate::New(
[](const v8::Arguments &args) -> v8::Handle<v8::Value>
{
v8::String::AsciiValue ascii(args[0]);
std::cout << *ascii << "\n";
}));
Persistent<Context> context = Context::New(NULL, global);
Questo funziona bene per qualsiasi funzione JavaScript globale che è o senza stato o riferimenti a C globale ++ variabile (cioè std::cout
) . Ma cosa succede se vogliamo che la nostra funzione JavaScript globale faccia riferimento a una variabile C++ non globale? Ad esempio, supponiamo di creare diversi diversi contesti JavaScript ciascuno con la propria funzione globale print
che utilizza un diverso C++ std::ostream
? Se i modelli di funzione v8 usati std::function
oggetti invece di puntatori a funzione, l'avremmo fatto qualcosa di simile:
Persistent<Context> create_context(std::ostream &out)
{
Handle<ObjectTemplate> global = ObjectTemplate::New();
global->Set(String::New("print"), FunctionTemplate::New(
[&out](const v8::Arguments &args) -> v8::Handle<v8::Value>
{
v8::String::AsciiValue ascii(args[0]);
out << *ascii << "\n";
}));
return Context::New(NULL, global);
}
Purtroppo, v8 non sembra a sostegno di questa. Presumo (spero?) Che v8 abbia un modo di fare qualcosa di funzionalmente equivalente, ma mi trovo sconcertato dal Doxygen per v8::FunctionTemplate
. Chiunque avesse tentato qualcosa di simile sarebbe disposto a distillare il processo in qualcosa di più comprensibile? Vorrei anche imparare come creare un'istanza globale di un oggetto JavaScript che è associato a un'istanza esistente, non globale di un oggetto C++.