// 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已更改,为什么?
答案 0 :(得分:1)
ReleaseIntArrayElements()会提交您所做的任何更改。 String是不可变的,这就是为什么ReleaseStringUTFChars()没有第四个参数。我想说这两个例子都是无效的,因为它们在发布时不提供相同的地址。