如何修改JNI String的每一个char码?

How to modify each char code of JNI String?

我的 class 中有一个函数用于 android。

    private String modify(String s) {
        char[] o = s.toCharArray();
        for (int i = 0; i < o.length; i++) {
            int x = o[i];
            o[i] = (char) (x - 125);
        }
        return String.valueOf(o);
    }

我想在 JNI 方法中实现类似的功能。意思是,取一个 JNI 字符串,转换为 char 数组,修改 char 数组中每个 char 的 charcode 和修改后的 char 数组中的 return JNI 字符串。

你能指导我吗?

在 jni 中,您可以使用 GetStringCharsjstring 获取 const jchar*,在本地将新的 jchar 值存储在数组中,并将其作为新字符串 return。代码如下:

C++ 版本

#include <jni.h>
#include <string>
#include <vector>


extern "C" JNIEXPORT jstring JNICALL
Java_com_example_jnitester_MainActivity_modify(
        JNIEnv* env,
        jobject /* this */,
        jstring str) {

    // Get jchar (2 bytes - its in unicode - not UTF) array of java string.
    // This can only be const jchar*, so you cannot modify it.
    jsize len = env->GetStringLength(str);
    jboolean isCopy;
    const jchar * strChars = env->GetStringChars(str, &isCopy);

    // Prepare new array of jchar, which will store new value
    std::vector<jchar> newStr;
    newStr.resize(len);

    // Do logic on it
    for (std::size_t i = 0; i < newStr.size(); i++) {
        int x = strChars[i];
        newStr[i] = (char) (x - 125);
    }

    if (isCopy == JNI_TRUE) {
        env->ReleaseStringChars(str, strChars);
    }

    // Return as a new java string
    return env->NewString(newStr.data(), newStr.size());
}

仅限 C 版本:

#include <jni.h>
#include <memory.h>

JNIEXPORT jstring JNICALL
Java_com_example_jnitester_MainActivity_modify(
        JNIEnv* env,
        jobject this,
        jstring str) {

    // Get jchar (2 bytes - its in unicode - not UTF) array of java string.
    // This can only be const jchar*, so you cannot modify it.
    jsize len = (*env)->GetStringLength(env, str);
    jboolean isCopy;
    const jchar * strChars = (*env)->GetStringChars(env, str, &isCopy);

    // Prepare new array of jchar, which will store new value
    jchar* newStr = (jchar*)malloc(len * 2 + 2);

    // Do logic on it
    for (size_t i = 0; i < len; i++) {
        int x = strChars[i];
        newStr[i] = (char) (x - 125);
    }

    if (isCopy == JNI_TRUE) {
       (*env)->ReleaseStringChars(env, str, strChars);
    }

    // Return as a new java string
    jstring resStr = (*env)->NewString(env, newStr, len);
    free(newStr);
    return resStr;
}