2

最終的に Raspberry Pi で実行されるDAB 開発ボード用の Node.js フロントエンドを作成しています。私は Java と Web の開発者で、C++ とさまざまなタイプの文字列間の変換に苦労しています。

DAB ボードには、多数の便利な機能を備えた C++ SDK が付属しています。で利用可能なプログラムの数を取得できますGetTotalProgram()GetProgramNameプログラムの名前を取得するために呼び出すことができるプログラムごとに、次のようにします。

GetProgramName(char mode, long dabIndex, char namemode, wchar_t * programName)

...ここで、またはをmode意味し、長い名前または短い名前を意味します。プログラムの名前は に返されます。FMDABnamemodeprogramName

を に変換するために、wchar_t *programName使用v8::Stringしているこのスニペットを見つけ、次の基本を理解しました。

  wchar_t buff[300];
  char cbuff[600];
  GetProgramName(0, i, 1, buff);
  wcstombs( cbuff, buff, wcslen(buff) );
  Local<String> str = String::NewFromUtf8(isolate, (const char *) cbuff, v8::String::kNormalString, wcslen(buff));

利用可能なプログラムを反復処理し、以下を構築しますv8::Array

void GetPrograms(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);

  wchar_t buff[300];
  char cbuff[600];
  int numberOfPrograms, i;

  numberOfPrograms = GetTotalProgram();
  Local<v8::Array> ARRAY = Array::New(isolate, totalprogram);

  for (i = 0; i < numberOfPrograms; i++) {
    if (GetProgramName(0, i, 1, buff)) {
      wcstombs( cbuff, buff, wcslen(buff) );
      Local<String> str = String::NewFromUtf8(isolate, (const char *) cbuff, v8::String::kNormalString, wcslen(buff));
      Local<Object> obj = Object::New(isolate);
      obj->Set(String::NewFromUtf8(isolate, "name"), str);
      ARRAY->Set(i, obj);
    }
  }
  args.GetReturnValue().Set(ARRAY);
}

Node アプリから C++ メソッドを呼び出します。

var programs = ext.getPrograms();
for (var i = 0; i < programs.length; i++) {
  console.log(programs[i][name]);
}

Æこれはほとんどの場合機能しますが、プログラムの名前に, Ø,のような非 ASCII 文字が含まれている場合、ARRAYÅ次の要素の名前は壊れています。

console.log予想される出力と比較して、Node スニペットが実際に出力するもの ( ) は次のとおりです。

| ACTUAL    | EXPECTED   |
| --------- | ---------- |
| NRK SUPER | NRK SUPER  |
| NRK VUPER | NRK VÆR    |
| NRK P1 ER | NRK P1     |

非ASCII文字により、次の文字がwcstombsコピーされずに、次の文字が早期に終了するようです。

なぜこれが起こるのですか?v8::Stringmy からを作成するより良い方法はありwchar_tますか?

注:wcstombsこの問題をRaspberry Pi で実行する場合 のメソッドに切り分けることができました。次のコード:

#include <stdio.h>
#include <string>
#include <cstring>
#include <cstdlib>

char cbuff[600];
wchar_t buff[300] = L"ABCø123abc";

int main( int argc, const char* argv[] ) {
    wcstombs( cbuff, buff, wcslen(buff) );
    wprintf(L"wcslen of wchar_t array: %u - strlen of char array: %u\n", (char) wcslen(buff), strlen(cbuff));
}

Mac で実行すると
wcslen of wchar_t array: 10 - strlen of char array: 10が出力
されますが、Raspberry で実行すると出力されます。つまり、文字の前の文字
wcslen of wchar_t array: 10 - strlen of char array: 3のみをカウントします。ø

これは、この未回答の質問に似ています。

4

3 に答える 3

3
WCHAR str[256];0
... // fill str array here
Local<String> v8str = String::NewFromTwoByte(isolate, (const uint16_t *) str);

andキャスト::NewFromTwoByteの代わりの使用法に注意してください。::NewFromUtf8(const uint16_t *)

::NewFromTwoByteUTF-16 データから新しい文字列を割り当てます。

于 2016-11-07T09:30:10.313 に答える
0

wcstombs の最後のパラメーターが問題の原因だと思います。しようとする代わりに

 wcstombs( cbuff, buff, wcslen(buff) );

試す

memset(cbuff, 0, sizeof(cbuff));
wcstombs( cbuff, buff, sizeof(cbuff) );
于 2015-08-18T11:55:42.180 に答える