JNIの文字列操作

Javaでは、作成しStringたオブジェクトは非常に簡単で、かつ使用できるStringメソッドクラスの様々な文字列を操作するのは非常に簡単です。JNIは、しかし、が、jstringクラスは、Javaを表すStringクラスを、しかし、jstring文字列を操作するために、任意の機能を提供していません。

エンコード形式

文字列定数のために、例えば"abc"、JavaでありString表すオブジェクト、および表すUTF-16文字列(つまり、ダブルバイトコードである)形式。JNIでは、それはcharしかし、符号化形式として、ポインタの種類が表されていますmodified UTF-8

だから何であるmodified UTF-8符号化形式は?実際には、あるUTF-8フォーマットは非常に似ていますが、少し違います

  • ヌル文字(値0)でUTF-8バイトで表され、但しmodified UTF-8、バイトは2で表されます。
  • バイト、2バイト、3バイトの両方が同じで符号化された、文字で表すことができます。
  • 文字を必要に応じて4バイトの場合、modified。 UTF-82つの3バイトが達成使用。

あなたが理解したい場合UTF-8modified UTF-8エンコーディング形式、最後のリンクを参照してください。

文字列操作のためのJNI関数は、両方のフォーマットのバージョンを持っています。今、私は2つのエンコード形式一般的な説明の文字列操作関数のために行います。

UTF-16文字列関数

NEWSTRING

jstring NewString(JNIEnv *env, const jchar *unicodeChars, jsize len);
复制代码

パラメータ

  • jchar *unicodeChars:ポインタUnicodeのポインタ文字列をエンコードされました。
  • jsize len:文字列の長さ。

NewString使用するUnicodeエンコードされた文字のJava配列を作成するStringオブジェクトを。

使用NewString鍵は、あなたが使用しなければならないということであるUnicodeエンコードされた文字列を、ここだUnicodeを指し、一般的にコーディングUTF-16コード。しかし、どのように取得するUTF-16エンコードされた文字列にそれを、この問題をこの資料の範囲を超えていますが、Androidの開発では、そこにあるString16クラスは、コンストラクタは、文字列定数に置くことができるUTF-16エンコードされた文字列を。

GetStringLength

jsize GetStringLength(JNIEnv *env, jstring string);
复制代码

パラメータ

  • jstring string:JavaのStringオブジェクト。

GetStringLength関数は、文字列の長さを返すとJava String返される文字列の長さは同じであり、例えばString s = "中国";、Java文字列の長さは2であり、そして例えばString s = "China";、弦5の長さ。

GetStringChars

const jchar * GetStringChars(JNIEnv *env, jstring string, jboolean *isCopy);
复制代码

パラメータ

  • jstring string:JavaはあるStringオブジェクト
  • jboolean * isCopy:もしisCopyないNULL、と生成された関数は、文字列のコピーである*isCopyJNI_TRUEのコピーは、生成されていない場合は、*isCopyの値をJNI_FALSE

GetStringCharsそれへのポインタを返しUnicodeエンコードされた文字の配列(おそらくはポインタへのポインタNULL)。このポインタは、元の文字列の配列を指すことは、仮想マシンを実現によって、コピーされた文字の配列を指してもよいです。コピーが発生した場合、ネイティブの文字列を解放する必要があるが必要ですReleaseStringChars

ReleaseStringChars

void ReleaseStringChars(JNIEnv *env, jstring string, const jchar *chars);
复制代码

パラメータ

  • jstring string:JavaはあるStringオブジェクト
  • jchar *chars:によって指さGetStringCharsのリターンUnicode文字の符号化された配列

ReleaseStringCharsではない彼らの機能(コピーが発生した場合)ローカルの文字列を解放しませんが、仮想マシンにアクセスもはやネイティブコードに気づくためにjchar *chars、仮想マシンと、その後、処理方法を決定します。

GetStringRegion

void GetStringRegion(JNIEnv *env, jstring str, jsize start, 
                    jsize len, jchar *buf);
复制代码

パラメータ

  • jstring str:JavaはあるStringオブジェクト
  • jsize start:開始位置のコピー
  • jsize len:コピー長
  • jchar *buf:コピー先バッファ

GetStringRegion機能start始まり、コピーlenの長さはUnicode文字buf真ん中。

GetStringCritical&ReleaseStringCriticalの

const jchar * GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy);
void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *carray);
复制代码

Get/ReleaseStringCritical機能とGet/ReleaseStringChars使用および機能における機能は同じです。つまり、GetStringCritical関数は、元の文字列へのポインタへのポインタを返すことができる、または実装し、仮想マシンに応じて、ソース文字列のポインタのコピーへのポインタを返します。コピーが発生した場合は、必要なReleaseStringCritial仮想マシンをローカル操作を解除通知します。

修正UTF-8文字列関数

NewStringUTF

jstring NewStringUTF(JNIEnv *env, const char *bytes);
复制代码

NewStringUTF第2のパラメータは、const char *bytesあるmodified UTF-8符号化されたバイト配列。

modified UTF-8JNIは、このフォーマット文字列と使用される仮想マシンの文字列として、独自のフォーマットです。

使用JNI modified UTF-8文字列型であるコードは、例えば、次の2行のコードは、この文字列を使用して符号化されます

const char * bytes1 = "中国";
const char * bytes2 = "China";
复制代码

文字列定数ので、デフォルトで作成されるmodified UTF-8ので、エンコーディングNewStringUTF最も一般的に、すべてのJava取得するために使用されているString関数オブジェクトを。

GetStringUTFLength

jsize GetStringUTFLength(JNIEnv *env, jstring string);
复制代码

パラメータ

  • jstring string:JavaはあるStringオブジェクト

GetStringUTFLengthこの関数は返すmodified UTF-8バイト長エンコード形式の文字列を。

、ことに注意してくださいGetStringUTFLengthそれはのバイト長を返すGetStringLengthリターン文字長を。一つは、文字が強調され、バイトを強調することであるが、これは何か他のものです。例えば、Java文字列String s = "中国"GetStringUTFLength6の値は、長さが6バイトの代表を返し、GetStringLength戻り値は2であり、長さは2つの文字を表します。

GetStringUTFChars

const char * GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy);
复制代码

パラメータ

  • jstring string:JavaのStringオブジェクト
  • jboolean * isCopy:もしisCopyないNULLし、その後、元の文字列のコピーの機能であれば*isCopy値がJNI_TRUE、その後、コピーが発生しない場合は*isCopyJNI_FALSE

GetStringUTFChars機能はへのポインタを返すmodified UTF-8エンコードされたバイト配列のポインタを。

パラメータは、からisCopy見ることができ、GetStringUTFChars関数はバイト配列を指すポインタを返す文字列が離れて指し示すことができる、それがコピーされた文字列を指してもよいです。イベントのコピーは、その後、時間のこのコピーを必要としない場合は、あなたが呼び出すことができ、解放する必要があるReleaseStringUTFChars機能を。

ReleaseStringUTFChars

void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf);
复制代码

パラメータ

  • jstring string:JavaはあるStringオブジェクト
  • const char *utf:によってGetStringUTFChars買収。

ReleaseStringUTFChars機能は単に、ネイティブコードはもはやアクセスの仮想マシンに通知const char *utfする仮想マシンに依存した後、処理動作。

GetStringUTFRegion

void GetStringUTFRegion(JNIEnv *env, jstring str, jsize start, 
                        jsize len, char *buf);
复制代码

GetStringUTFRegion機能とGetStringRegion機能のパラメータがあることを除いて、同じGetStringUTFRegionバッファの機能から文字にコピーされますUnicode変換されたmodified UTF-8形式。

使用

通常の状況下で、我々は、JNIのデフォルトを使用することを選択したmodified UTF-8ことが便利であるので、トランスコーディングを必要とせず、エンコードされた文字列を。私たちが使用しなければならない場合やUTF-16エンコードされた文字列を、あなたは変換する必要があります。

だから、より良いハンドリング文字列その中にどのようにJNI層?あなたがC ++開発JNIを使用している場合は、JNI層を使用することができますstring文字列クラスを操作することができますが、C言語を使用する場合は、ステップ・プロセスによって文字ポインタのステップを使用する必要があります。

たとえば、Javaクラスが持つnativeメソッドを

public class Hello
{
    native string getHelloFromJNI(String name);
}
复制代码

JNIとして実装対応する層に

static jstring getHello(JNIEnv *env, jobject thiz, jstring name)
{
    // 从Java的String对象转换为本地表示
    const char *c_name = env->GetStringUTFChars(name, NULL);
    // 使用C++的string进行字符串拼接
    string str("Hello, ");
    str.append(c_name);
    str.append("!");
    env->ReleaseStringUTFChars(name, c_name);
    // 创建Java的String对象并返回
    return env->NewStringUTF(str.c_str());
}
复制代码

参照

修飾されたUTF-8エンコーディング

docs.oracle.com/javase/7/do...

ユニコード(UTF-8、UTF-16など)の符号化

baike.baidu.com/item/Unicod...

おすすめ

転載: juejin.im/post/5d303920f265da1bcf5e1378