1
// example-1: GetStringUTFChars()
public class Prompt
{
    // native method that prints a prompt and reads a line
    private native String getLine(String prompt);
    public static void main(String args[])
    {
        Prompt p = new Prompt();
        String temp = new String("Type a line: ");
        String input = p.getLine(temp);
        System.out.println("User typed: " + input);
        System.out.println(temp);
    }
    static
    {
        System.loadLibrary("Prompt");
    }
}
/*
javac Prompt.java
javah Prompt
get a file: Prompt.h
*/

#include "Prompt.h"
#include <stdio.h>
#include <string.h>
JNIEXPORT jstring JNICALL Java_Prompt_getLine (JNIEnv *env, jobject obj, jstring prompt)
{
    char buf[128];
    const jbyte *str;
    jboolean isCp;
    str = (*env)->GetStringUTFChars(env, prompt, &isCp);
    if (str == NULL) {
        return NULL; /* OutOfMemoryError already thrown */
    }
    if(isCp == JNI_TRUE)
    {
        strcpy(str,"12345");
    }
    printf("%s", str);
    (*env)->ReleaseStringUTFChars(env, prompt, str);
    /* We assume here that the user does not type more than
     * 127 characters */
    scanf("%s", buf);
    return (*env)->NewStringUTF(env, buf);
}
/*
set java_inc=E:\FILES\java\jdk1.6.0_29\include
cl -I%java_inc% -I%java_inc%\win32 -LD Prompt.c -FePrompt.dll
*/
/* output
the output of running class Prompt.class:
12345jdkfjkdjfkdf
User typed: jdkfjkdjfkdf
Type a line:

the output demonstrates that String instance temp did not changed, and isCopy is JNI_TRUE
*/


// example-2: GetIntArrayElements()
public class TestJNI
{
    public native void intArray(int[] ii);
    public static void main(String[] args)
    {
        System.loadLibrary("TestJNI");
        TestJNI jni = new TestJNI();
        int[] ii = new int[4];
        for(int i = 0; i < ii.length; i++)
        {
            ii[i] = i;
        }
        jni.intArray(ii);
        for(int i = 0; i < ii.length; i++)
        {
            System.out.println(ii[i]);
        }
    }
}
/*
output:
isCopy: 1
100
101
102
103

the output shows that ii has been changed, but isCopy is JNI_TRUE
*/

#include "TestJNI.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_TestJNI_intArray(JNIEnv *env, jobject obj, jintArray intArr)
{
    jboolean isCp;
    int i;
    jsize len = (*env)->GetArrayLength(env, intArr);
    jint *arr = (*env)->GetIntArrayElements(env, intArr, &isCp);
    if(isCp == JNI_TRUE)
    {
        printf("isCopy: JNI_TRUE\n");
    }
    for(i = 0; i < len; i++)
    {
        arr[i] = 100 + i;
    }
    (*env)->ReleaseIntArrayElements(env, intArr, arr, 0);
}
/*
output:
isCopy: 1
100
101
102
103

the output shows that ii has been changed, but isCopy is JNI_TRUE
*/

示例 1:输出表明 String 实例 temp 没有更改,并且 isCopy 为 JNI_TRUE 示例 2:输出显示 ii 已更改,但如果 isCopy 设置为 JNI_TRUE,则 isCopy 为 JNI_TRUE,这意味着 arr 指向一个新数组,但是 intArr 改变了,为什么?

4

1 回答 1

1

ReleaseIntArrayElements() 提交您所做的任何更改。String 是不可变的,这就是 ReleaseStringUTFChars() 没有第四个参数的原因。我想说这两个示例都是无效的,因为它们在发布时不提供相同的地址。

于 2012-05-09T23:54:47.247 回答