Search code examples
c++v8embedded-v8

v8 C++ Api: pass non-English strings from JavaScript to c++


In my c++ code I have:

Handle<ObjectTemplate> globalTemplate = ObjectTemplate::New();
globalTemplate->Set( String::New("print"), FunctionTemplate::New( printMessage ));
Handle<Context> context = Context::New( NULL, globalTemplate );

The printMessage function is defined as:

Handle<Value> printMessage(const Arguments& args) 
{
    Locker locker;
    HandleScope scope;

    if( args.Length() ) 
    {
        String::Utf8Value message( args[0]->ToString() );

        if( message.length() ) 
        {
            //Print the message to stdout
            printf( "%s", *message );

            bool newline = true;
            if(args.Length() == 2) 
            {
                newline = args[1]->ToBoolean()->BooleanValue();
            }

            if(newline) printf("\n");

            return scope.Close( Boolean::New( true ) );
        }
    } 

    return Undefined();
}

when I call this function from JavaScript:

print("Привет");

I see "пїЅпїЅпїЅпїЅпїЅпїЅ" instead of string.

What was wrong with this code?


Solution

  • The code looks correct, so as @xaxxon suggested, I'd double-check that the terminal you use for output can deal with non-ASCII characters, and that the input file (if any) is encoded correctly.

    Also, your V8 versions appears to be pretty old (e.g. the HandleScope constructor always takes an Isolate* parameter these days), so it's also possible that you're experiencing some old bug that has since been fixed.

    For reference, the official sample shell does things almost the same way, and on my machine at least works fine with your test string:

    void Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
      bool first = true;
      for (int i = 0; i < args.Length(); i++) {
        v8::HandleScope handle_scope(args.GetIsolate());
        if (first) {
          first = false;
        } else {
          printf(" ");
        }
        v8::String::Utf8Value str(args[i]);
        const char* cstr = ToCString(str);
        printf("%s", cstr);
      }
      printf("\n");
      fflush(stdout);
    }