[解決済み] jstring(JNI) から std::string(c++) へ utf8 文字で変換する。
2022-02-28 23:32:46
質問
変換方法
jstring
(JNI)から
std::string
(c++) を使って
utf8
文字ですか?
これは私のコードですが、非UTF8文字では動作しましたが、UTF8文字では間違っています。
std::string jstring2string(JNIEnv *env, jstring jStr){
const char *cstr = env->GetStringUTFChars(jStr, NULL);
std::string str = std::string(cstr);
env->ReleaseStringUTFChars(jStr, str);
return str;
}
解決方法は?
何度も何度も解決策を探した結果、ある方法を見つけました。
javaでは、ユニコード文字が2バイトでエンコードされます(
utf16
となります。
jstring
はコンテナ文字
utf16
.
std::string
は基本的に文字ではなくバイト列なので、もし
jstring
から
JNI
から
c++
に変換しています。
utf16
をバイトに変換します。
文書中 JNI関数 jstringから文字列を取得するための関数が2つあります。
// Returns a pointer to the array of Unicode characters of the string.
// This pointer is valid until ReleaseStringchars() is called.
const jchar * GetStringChars(JNIEnv *env, jstring string, jboolean *isCopy);
// Returns a pointer to an array of bytes representing the string
// in modified UTF-8 encoding. This array is valid until it is released
// by ReleaseStringUTFChars().
const char * GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy);
GetStringUTFChars
を返します。
修正されたutf8
.
GetStringChars
は jbyte * を返すので、jbyte から char コードを読み込んで、c++ で char に変換します。
これは私の解決策です。
ascii
と
utf8
文字)を使用します。
std::string jstring2string(JNIEnv *env, jstring jStr) {
if (!jStr)
return "";
const jclass stringClass = env->GetObjectClass(jStr);
const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
const jbyteArray stringJbytes = (jbyteArray) env->CallObjectMethod(jStr, getBytes, env->NewStringUTF("UTF-8"));
size_t length = (size_t) env->GetArrayLength(stringJbytes);
jbyte* pBytes = env->GetByteArrayElements(stringJbytes, NULL);
std::string ret = std::string((char *)pBytes, length);
env->ReleaseByteArrayElements(stringJbytes, pBytes, JNI_ABORT);
env->DeleteLocalRef(stringJbytes);
env->DeleteLocalRef(stringClass);
return ret;
}
関連
-
[解決済み】Android: Intent エラーを処理するアクティビティは見つかりませんでしたか?どのように解決するのか
-
[解決済み] 現在のテーマでスタイル 'coordinatorLayoutStyle' を見つけることができませんでした。
-
[解決済み】Android Studio AVD - Emulator: 終了コード 1 でプロセスが終了
-
[解決済み】ビットマップを保存する場所について
-
[解決済み】SDKの場所がandroid studioで見つからない。
-
[解決済み] TypeError: cb.apply は関数ではありません。
-
[解決済み] Androidでイメージビューの背景を透明に設定する
-
[解決済み] error: 'this' 引数に xxx を渡すと修飾子が消える
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
-
[解決済み】std::stringをconstexprで使用することは可能ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】コンテンツには、id属性が「android.R.id.list」であるListViewが必要です。
-
[解決済み】シンボル 'AppCompatActivity' を解決できない。
-
[解決済み】Android Studioの初回起動。Android SDKアドオンリストにアクセスできない
-
[解決済み】Android Studio。adbバージョン」の結果を取得できない
-
[解決済み】SDKの場所がandroid studioで見つからない。
-
[解決済み] Mockito lenient() を使用する場合
-
[解決済み] Android Fragment no view found for ID?
-
[解決済み] setBackgroundDrawable() 非推奨
-
[解決済み] Android Fragment onAttach() 非推奨
-
[解決済み] Android M パーミッション : shouldShowRequestPermissionRationale()関数の使用方法について混乱しています。