C- JNI -WRAPPER在Windows上崩溃了JVM



我已经写了一个jni-wrapper,但直到今天才在Linux上使用它。现在,我将其编译为Windows,JVM用此本机方法崩溃:如果我删除了ReleaseStringUTFCharsfree调用它也可以在Windows上工作,但是有趣的是,为什么在Linux中起作用,而在Windows中不起作用?(我使用Windows 10-64bit)。从我的经验中

void onMessageReceived(char* topic, char* timestamp, char* id, char* value) {
JNIEnv * g_env;
int getEnvStat = (*g_vm)->GetEnv(g_vm, (void **) &g_env, JNI_VERSION_1_8);
if (getEnvStat == JNI_EDETACHED) {
    if ((*g_vm)->AttachCurrentThread(g_vm, (void **) &g_env, NULL) != 0) {
        puts("Failed to attach");
        fflush(stdout);
    }
}
if (methodHandleMessage) {
} else {
    jclass clazz = (*g_env)->GetObjectClass(g_env, store_callback);
    methodHandleMessage = (*g_env)->GetMethodID(g_env, clazz, "handleMessage", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
}
jstring j_topic = (*g_env)->NewStringUTF(g_env, topic);
jstring j_timestamp = (*g_env)->NewStringUTF(g_env, timestamp);
jstring j_value = (*g_env)->NewStringUTF(g_env, value);
jstring j_id = (*g_env)->NewStringUTF(g_env, id);

(*g_env)->CallVoidMethod(g_env, store_callback, methodHandleMessage, j_topic, j_timestamp, j_id, j_value);
//HERE IS THE PROBLEM:
(*g_env)->ReleaseStringUTFChars(g_env, j_topic, topic);
(*g_env)->ReleaseStringUTFChars(g_env, j_timestamp, timestamp);
(*g_env)->ReleaseStringUTFChars(g_env, j_value, value);
(*g_env)->ReleaseStringUTFChars(g_env, j_id, id);
//
(*g_vm)->DetachCurrentThread(g_vm);
}

void rep_actor(zsock_t *pipe, void *args) {
zsock_signal(pipe, 0);
while (!zsys_interrupted) {
    char* timestamp;
    char* sender;
    char* command;
    char* message;
    zsock_recv(reply, "ssss", &timestamp, &sender, &command, &message);
    char* result = onRequestReceived(timestamp, sender, command, message);
    zsock_send(reply, "s", result);
//HERE IS THE PROBLEM:
    free(timestamp);
    free(sender);
    free(command);
    free(message);
    free(result);
//
}
}

发生了错误,因为您两次免费内存。第一次 - 通过在onMessageReceived()的内部调用ReleaseStringUTFChars(),第二次 - 在onMessageReceived()外部,您可以在每个发布的指针上调用free()

重要
您不需要在Java Enviroment内部创建的对象(env->New*()方法的调用)中创建的对象。在您的情况下:

// j_topic - it's a pointer for object inside of java heap
// garbage collector will free this memory
jstring j_topic = env->NewStringUTF(topic);

ReleaseStringUTFChars()的调用在这里是不合适的。仅当您使用GetStringUTFChars()创建Java String本机字符串时才使用:

// j_topic - string inside of java heap
const char* native_str = env->GetStringUTFChars(j_topic, isCopy);
// your logic for native_str array
// informs the VM that the native code no longer needs access to native_str
env->ReleaseStringUTFChars(j_topic, native_str);

查看Javadoc的方法GetStringUTFChars()ReleaseStringUTFChars()-您应该一起使用它们。

最新更新