0

数か月前、私は JNI を使用して C API をラップする Java API を作成しました。C API は char 文字列を使用し、GetStringUTFChars を使用して Java 文字列から C 文字列を作成しました。

非 ASCII 文字で発生する可能性のある問題について考えるのを怠っていました。

それ以来、C API の作成者は、wchar_t 文字列を要求または返す C 関数のそれぞれに相当するワイド文字を作成しました。Java API を更新してこれらのワイド文字関数を使用し、非 ASCII 文字に関する問題を解決したいと考えています。

JNI のドキュメントを調べた結果、GetStringChars メソッドまたは GetStringRegion メソッドを使用することの相対的な利点に少し戸惑いました。

wchar_t 文字のサイズが Windows と Linux で異なることは認識しており、C 文字列を作成する (そして後で Java 文字列に変換する) 最も効率的な方法がわかりません。

これは私が現時点で持っているコードで、1文字あたり2バイトの文字列を作成すると思います:

int len;
jchar *Src;

len = (*env)->GetStringLength(env, jSrc);
printf("Length of jSrc is %d\n", len);

Src = (jchar *)malloc((len + 1)*sizeof(jchar));
(*env)->GetStringRegion(env, jSrc, 0, len, Src);
Src[len] = '\0';

ただし、wchar_t のサイズが jchar と異なる場合は、これを変更する必要があります。

4

1 に答える 1

2

C API 作成者は、一歩下がってUTF-8で再実装することをいとわないでしょうか? :) あなたの仕事は本質的に消えてしまい、必要なのはGetStringUTFChars/だけNewStringUTFです。

jcharに型定義されており、 UTF-16であるunsigned shortJVM と同等です。したがって、2バイトのUTF-16もあるWindowsでは、提示したコードを廃止できます。生のバイトをコピーするだけで、それに応じて割り当てます。C API 呼び出しが終了したら、解放することを忘れないでください。jstring への変換を補完します。charwchar_tNewString

wchar_t私が認識している唯一の他のサイズは、 UTF-32である 4 バイト (最も顕著な Linux)です。ここで問題が発生します。UTF-32 は、何らかの方法で 4 バイトにパディングされた UTF-16 だけではありません。2 倍のメモリ量を割り当てることは、ほんの始まりにすぎません。十分に無料と思われるこのような変換を行うには、かなりの変換が必要です。

しかし、パフォーマンスをあまり求めておらず、Windows でのプレーン メモリのコピーをあきらめても構わないと思っている場合は、jstringUTF-8 (JNI が文書化された機能をネイティブに提供するもの) に移動し、次に UTF-8 から UTF-16 に移動することをお勧めします。に応じてUTF-32 sizeof(wchar_t)。各プラットフォームが提供するバイト オーダーと UTF エンコーディングについて、仮定はありません。あなたはそれを気にしているようです、私はあなたがsizeof(jchar)目に見える宇宙のほとんどが2であることをチェックしていることがわかります:)

于 2013-01-15T12:03:03.803 に答える