v8 C++ Api: передавать неанглийские строки из JavaScript в C++

В моем коде С++ у меня есть:

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

Функция printMessage определяется как:

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();
}

когда я вызываю эту функцию из JavaScript:

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

Я вижу "пїЅпїЅпїЅпїЅпїЅпїЅ" вместо строки.

Что было не так с этим кодом?


person Khachatur    schedule 08.06.2017    source источник
comment
правильно ли настроена ваша консоль для отображения юникода? Может быть лучше вручную проверить целочисленные значения байтов, которые вы просматриваете, вместо того, чтобы распечатывать их, чтобы убедиться, что данные верны, а отображение данных не соответствует вашим ожиданиям или необработанные данные на самом деле неправильно.   -  person xaxxon    schedule 08.06.2017


Ответы (1)


Код выглядит правильно, поэтому, как предложил @xaxxon, я бы еще раз проверил, что терминал, который вы используете для вывода, может работать с символами, отличными от ASCII, и что входной файл (если есть) закодирован правильно.

Кроме того, ваши версии V8 кажутся довольно старыми (например, конструктор HandleScope в наши дни всегда принимает параметр Isolate*), поэтому также возможно, что вы столкнулись с какой-то старой ошибкой, которая с тех пор была исправлена.

Для справки: официальный образец оболочки все почти так же, и на моей машине, по крайней мере, отлично работает с вашей тестовой строкой:

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);
}
person jmrk    schedule 08.06.2017
comment
да, я использую старый код из-за окончательного размера exe-файла (у меня около 2 МБ по сравнению с 8 МБ с последними исходниками). - person Khachatur; 08.06.2017