1

UChar *(つまりUnicode文字配列)を返すJNIを介してICU4C関数にアクセスしています... UChar配列の各メンバーを作成したローカルjbyte[]配列と同等にすることで、これをjbyteArrayに変換できました。次に、env-> SetByteArrayRegion()関数を使用してJavaに戻しました...これで、JavaにByte []配列がありますが、すべてがかなりぎこちないです。かもしれません...それが重要な場合はユニコード文字を使用しています...Javaでbyte[]をchar[]に正しく変換するにはどうすればよいですか?何かが正しくマッピングされていません...コードのスニペットは次のとおりです。


--- JNIコード(短くするために少し変更)---

static jint testFunction(JNIEnv* env, jclass c, jcharArray srcArray, jbyteArray destArray) {

    jchar* src = env->GetCharArrayElements(srcArray, NULL);
    int n = env->getArrayLength(srcArray);

    UChar *testStr = new UChar[n];
    jbyte destChr[n];

    //calling ICU4C function here    
    icu_function (src, testStr);   //takes source characters and returns UChar*

    for (int i=0; i<n; i++)
        destChr[i] = testStr[i];   //is this correct?

    delete testStr;
    env->SetByteArrayRegion(destArray, 0, n, destChr);
    env->ReleaseCharArrayElements(srcArray, src, JNI_ABORT);

    return (n); //anything for now
}

--Javaコード--stringwohoo= "ABCD bal bla bla"; char [] myChars = wohoo.toCharArray();

byte[] myICUBytes = new byte[myChars.length];
int value = MyClass.testFunction (myChars, myICUBytes);

System.out.println(new String(myICUBytes)) ;// produces gibberish & weird symbols

私も試しました:System.out.println(new String(myICUBytes、Charset.forName( "UTF-16")))そしてそれは同じようにgebberishyです...。

ICU関数はUCharで適切なUnicode文字を返すことに注意してください*...jbyteArrayへの変換とJavaへの変換の間のどこかで混乱しています...

ヘルプ!

4

2 に答える 2

1
destChr[i] = testStr[i];   //is this correct?

これは問題のようです。

JNIタイプ

byte   jbyte    signed 8 bits
char   jchar    unsigned 16 bits

ICU4Cタイプ

UCharが16ビット幅の場合、wchar_tになるように定義します。常に署名されていないと見なされます。

wchar_tの幅が16ビットでない場合、GCC> = 4.4はUTF16文字列リテラルを処理できるため、UCharをuint16_tまたはchar16_tとして定義します。これにより、UCharの定義はプラットフォームに依存しますが、16ビットのwchar_t型のプラットフォームとの直接の文字列型の互換性が可能になります。

したがって、何かicu_functionが行われている可能性は別として、16ビット値を8ビット幅の型に適合させようとしています。

charJavaバイト配列を使用する必要がある場合は、Unicodeエンコーディングにトランスコードして8ビットタイプに変換することをお勧めします。

いくつかのCコードを言い換えると:

UChar *utf16 = (UChar*) malloc(len16 * sizeof(UChar));
//TODO: fill data
// convert to UTF-8
UConverter *encoding = ucnv_open("UTF-8", &status);
int len8 = ucnv_fromUChars(encoding, NULL, 0, utf16, len16, &status);
char *utf8 = (char*) malloc(len8 * sizeof(char));
ucnv_fromUChars(encoding, utf8, len8, utf16, len16, &status);
ucnv_close(encoding);
//TODO: char to jbyte

次に、を使用してこれをJava文字列にトランスコードできますnew String(myICUBytes, "UTF-8")

UTF-8はすでにサンプルコードに含まれており、エンディアンを気にする必要がないため、UTF-8を使用しました。必要に応じて、CをC++に変換します。

于 2011-02-22T21:40:09.727 に答える
0

ICU4Jの使用を検討しましたか?

また、バイトを文字列に変換するときは、文字エンコードを指定する必要があります。問題のライブラリに精通していないので、これ以上アドバイスすることはできませんが、おそらくこれは「UTF-16」または同様のものになるでしょうか。

また、印刷先の端末で正しい文字セットが使用されていないか、適切なグリフが使用できないために、単に表示エラーが発生する可能性があることにも注意してください。

于 2011-02-22T19:28:32.107 に答える