如何在 JNI 线程和本机线程之间安全地共享字符串

问题描述 投票:0回答:0

情况:

我正在开发一个 Java 应用程序,我需要使用 JNI 将一个字符串变量传递给本机代码。本机代码会将 String 变量的引用存储为全局变量,并使用它来访问 IPC 上下文中的变量值。

问题:

我面临的问题是全局变量指向的内存位置和我们访问信息变量时引用的内存位置不同。这会导致程序在尝试访问无效内存位置时崩溃。 值得注意的是,Java 端由一个线程设置,native 端由 IPC 上下文中的另一个线程访问。 一个更重要的信息是,所有进程都从同一个内存指针读取(只有一个进程为自己设置全局变量,而不是让其他进程读取它)。不确定如何允许不同的进程从同一内存地址读取。

我曾尝试使用 GetCharArrayElements() 和 ReleaseCharArrayElements() 方法来访问字符串的字符数组,但没有帮助。我也尝试使用 GetStringUTFChars() 和 ReleaseStringUTFChars() 方法,但它们也没有解决问题。

我在访问信息字符串的值之前和之后添加了日志行来打印指向 jstring 的指针的地址,看起来指向 jstring 的指针在 Java 和本机线程之间发生了变化。

伪代码:

Java 方面:

/ Create a string variable
String information = "This is the information string";

// Pass the string variable to native code using JNI
nativeMethod(information);

// Native method declaration
public static native void nativeMethod(String information);

原生方:

// Global information variable (static/non-static both doesnt help)
static jstring globalInformation;

JNIEXPORT void JNICALL Java_className_nativeMethod(JNIEnv* env, jobject obj, jstring information) {
    globalInformation = static_cast<jstring>(env->NewGlobalRef(information));
    printf("Set globalInformation address: %p\n", (void*)&globalInformation);
}

void printInformation() {
    printf("Read globalInformation address: %p\n", (void*)&globalInformation);
    const char* informationValue = (*env)->GetStringUTFChars(env, globalInformation, NULL);
    if (informationValue == NULL) {
        printf("Unable to access information value\n");
    } else {
        printf("%s\n", informationValue);
        (*env)->ReleaseStringUTFChars(env, globalInformation, informationValue);
    }
}

输出:

Set globalInformation address: 0xb45deb78
Read globalInformation address: 0xb1f3e250
Unable to access information value

我将不胜感激有关如何解决此问题的任何指导。

android c++11 java-native-interface embedded-linux jnienv
© www.soinside.com 2019 - 2024. All rights reserved.