jni中java与C转换(一)

2014-11-24 02:43:15 · 作者: · 浏览: 3

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.递整型数组
本节例程将首次尝试在JNI框架内启用数组:C程序向Java程序返回一个定长的整型数组成的数组,Java程序将该数组打印输出。

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]);


return array;

}

Sample2.c涉及了两个jni.h定义的整型数 相关的数据类型:jint和jintArray,jint是在JNI框架内特有的整数类型。程序的第7行开辟出一个长度为10 的jint数组。然后依次向该数组中放入元素1-10。第11行至第16行不是程序的必须部分,纯粹是为了向读者们演示GetArrayLength() 和GetIntArrayElements()这两个函数的使用方法,前者是获取数组长度,后者则是获取数组的首地址以便于遍历数组。

3. 传递字符串数组
本节例程是对上节例程的进一步深化:虽然仍然是传递数组,但是数组的基类换成了字符串这样一种对象数据类型。Java程序将向C程序传入一个包含中文字符的字符串,C程序并没有处理这个字符串,而是开辟出一个新的字符串数组返回给Java程序,其中还包含两个汉字字符串。

Java程序的源代码如下。

代码清单15-10 在Linux平台上调用C函数的例程——Sample3

public class Sample3

{

public native String[] stringMethod(String text);


public static void main(String[] args) throws java.io.UnsupportedEncodingException

{

System.loadLibrary("Sample3");