1.传递字符串
到目前为止,我们还没有实现Java程序向C程序传递参数,或者C程序向Java程序传递参数。本例程将由Java程序向C程序传入一个字符串,C程序对该字符串转成大写形式后回传给Java程序。
Java源程序如下。
代码清单15-6 在Linux平台上调用C函数的例程——Sample1
public class Sample1
{
public native String stringMethod(String text);
public static void main(String[] args)
{
System.loadLibrary("Sample1");
Sample1 sample = new Sample1();
String text = sample.stringMethod("Thinking In Java");
System.out.println("stringMethod: " + text);
}
}
Sample1.java以“Thinking In Java”为参数调用libSample1.so中的函数stringMethod(),在得到返回的字符串后打印输出。
Sample1.c的源程序如下。
代码清单15-7 在Linux平台上调用C函数的例程——Sample1.c
#include
#include
JNIEXPORT jstring JNICALL Java_Sample1_stringMethod(JNIEnv *env, jobject obj, jstring string)
{
const char *str = (*env)->GetStringUTFChars(env, string, 0);
char cap[128];
strcpy(cap, str);
(*env)->ReleaseStringUTFChars(env, string, str);
int i=0;
for(i=0;i *(cap+i)=(char)toupper(*(cap+i)); return (*env)->NewStringUTF(env, cap); } 首先请注意函数头部分,函数接收一个jstring类 型的输入参数,并输出一个jstring类型的参数。jstring是jni.h中定义的数据类型,是JNI框架内特有的字符串类型,因为jni.h在 Sample1.h中被引入,因此在Sample1.c中无须再次引入。 程序的第4行是从JNI调用上下文中获取UTF编码的输入字符,将其放在指针str所指向 的一段内存中。第9行是释放这段内存。第13行是将经过大写转换的字符串予以返回,这一句使用了NewStringUTF()函数,将C语言的字符串指针 转换为JNI的jstring类型。JNIEnv也是在jni.h中定义的,代表JNI调用的上下文,GetStringUTFChars()、 ReleaseStringUTFChars()和NewStringUTF()均是JNIEnv的函数。 2.递整型数组 Java程序的源代码如下。 代码清单15-8 在Linux平台上调用C函数的例程——Sample2 public class Sample2 { public native int[] intMethod(); public static void main(String[] args) { System.loadLibrary("Sample2"); Sample2 sample=new Sample2(); int[] nums=sample.intMethod(); for(int i=0;i System.out.println(nums[i]); } } Sample2.java调用libSample2.so中的函数intMethod()。Sample2.c的源代码如下。 代码清单15-9 在Linux平台上调用C函数的例程——Sample2.c #include JNIEXPORT jintArray JNICALL Java_Sample2_intMethod(JNIEnv *env, jobject obj) { inti = 1; jintArray array;//定义数组对象 array = (*env)-> NewIntArray(env, 10); for(; i<= 10; i++) (*env)->SetIntArrayRegion(env, array, i-1, 1, &i); /* 获取数组对象的元素个数 */ int len = (*env)->GetArrayLength(env, array); /* 获取数组中的所有元素 */ jint* elems = (*env)-> GetIntArrayElements(env, array, 0); for(i=0; i printf("ELEMENT %d IS %d\n", i, elems[i]); } Sample2.c涉及了两个jni.h定义的整型数 相关的数据类型:jint和jintArray,jint是在JNI框架内特有的整数类型。程序的第7行开辟出一个长度为10 的jint数组。然后依次向该数组中放入元素1-10。第11行至第16行不是程序的必须部分,纯粹是为了向读者们演示GetArrayLength() 和GetIntArrayElements()这两个函数的使用方法,前者是获取数组长度,后者则是获取数组的首地址以便于遍历数组。 3. 传递字符串数组 Java程序的源代码如下。 代码清单15-10 在Linux平台上调用C函数的例程——Sample3 public class Sample3 { public native String[] stringMethod(String text); { System.loadLibrary("Sample3");
本节例程将首次尝试在JNI框架内启用数组:C程序向Java程序返回一个定长的整型数组成的数组,Java程序将该数组打印输出。
return array;
本节例程是对上节例程的进一步深化:虽然仍然是传递数组,但是数组的基类换成了字符串这样一种对象数据类型。Java程序将向C程序传入一个包含中文字符的字符串,C程序并没有处理这个字符串,而是开辟出一个新的字符串数组返回给Java程序,其中还包含两个汉字字符串。
public static void main(String[] args) throws java.io.UnsupportedEncodingException