Elias
Elias

Reputation: 234

V8: why is my function not available for JavaScript code?

I am trying to make some functions defined in c++ code available to JavaScript code running on v8.

Following some examples found over the web I was lead to believe that the following should work:

#include <stdio.h>
#include <v8.h>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>

v8::Handle< v8::Value > print( const v8::Arguments & args ) {
   for ( int i = 0; i < args.Length(); i++ )
   {
      v8::String::Utf8Value str( args[ i ] );
      std::cout << *str;
   }

   return v8::Undefined();
}

int main( int argc, char* argv[] ) {

   // Create a stack-allocated handle scope.
   v8::HandleScope handle_scope;

   // Make "print" available:
   v8::Handle< v8::ObjectTemplate > global = v8::ObjectTemplate::New();
   global->Set( v8::String::New( "print" ), v8::FunctionTemplate::New( print ) );

   // Create a new context.
   v8::Handle< v8::Context > context = v8::Context::New();
   // Enter the created context for compiling and
   // running the hello world script.
   v8::Context::Scope context_scope( context );

   // Create a string containing the JavaScript source code.
   v8::Handle< v8::String > source = v8::String::New(
      "\
      print( 'Hello' );\
      'Hello' + ', World!'\
      "
   );

   // Compile the source code.
   v8::Handle< v8::Script > script = v8::Script::Compile( source );

   // Run the script to get the result.
   v8::Handle< v8::Value > result = script->Run();

   return 0;
}

It does compile fine, but when I run the compiled program I always get an error:

<unknown>:6: Uncaught ReferenceError: print is not defined

What is that I am doing wrong?

Upvotes: 0

Views: 558

Answers (1)

jmrk
jmrk

Reputation: 40521

What's missing is that you're not doing anything with the global template you set up. If you look at the parameters you can pass to Context::New, you'll find that one can specify an object template for the global object there:

v8::Context::New(isolate, nullptr, global);

You should also set up an Isolate (to pass as isolate there); in fact v8::HandleScope handle_scope; shouldn't even compile without one, at least in the current version.

For more details, see the official documentation, which explains this as well as many other things: https://v8.dev/docs/embed

Upvotes: 1

Related Questions