jni中java与C转换(二)

2014-11-24 02:43:15 · 作者: · 浏览: 2
Sample3 sample = new Sample3();

String[] texts = sample.stringMethod("java编程思想");

for(int i=0;i

{

texts[i]=new String(texts[i].getBytes("ISO8859-1"),"GBK");

System.out.print( texts[i] );

}

System.out.println();

}

}

Sample3.java调用libSample3.so中的函数stringMethod()。Sample3.c的源代码如下:

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

#include

#include

#include

#define ARRAY_LENGTH 5

JNIEXPORT jobjectArray JNICALL Java_Sample3_stringMethod(JNIEnv *env, jobject obj, jstring string)

{

jclass objClass = (*env)->FindClass(env, "java/lang/String");

jobjectArray texts= (*env)->NewObjectArray(env, (jsize)ARRAY_LENGTH, objClass, 0);

jstring jstr;

char* sa[] = { "Hello,", "world!", "JNI", "很", "好玩" };

int i=0;

for(;i

{

jstr = (*env)->NewStringUTF( env, sa[i] );

(*env)->SetObjectArrayElement(env, texts, i, jstr);//必须放入jstring

}

return texts;

}

第9、10行是我们需要特别关注的地方:JNI框架并 没有定义专门的字符串数组,而是使用jobjectArray——对象数组,对象数组的基类是jclass,jclass是JNI框架内特有的类型,相当 于Java语言中的Class类型。在本例程中,通过FindClass()函数在JNI上下文中获取到java.lang.String的类型 (Class),并将其赋予jclass变量。

在例程中我们定义了一个长度为5的对象数组texts,并在程序的第18行向其中循环放入预先定义好的sa数组中的字符串,当然前置条件是使用NewStringUTF()函数将C语言的字符串转换为jstring类型。

本例程的另一个关注点是C程序向Java程序传递的中文字符,在Java程序中能否正常显 示的问题。在笔者的试验环境中,Sample3.c是在Linux平台上编辑的,其中的中文字符则是用支持GBK的输入法输入的,而Java程序采用 ISO8859_1字符集存放JNI调用的返回字符,因此在“代码清单15-10在Linux平台上调用C函数的例程——Sample3”的第14行中将 其转码后输出。

4.传递对象数组
本节例程演示的是C程序向Java程序传递对象数组,而且对象数组中存放的不再是字符串,而是一个在Java中自定义的、含有一个topic属性的MailInfo对象类型。

MailInfo对象定义如下。

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

public class MailInfo {

public String topic;

public String getTopic()

{

return this.topic;

}


public void setTopic(String topic)

{

this.topic=topic;

}

}

Java程序的源代码如下。

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

public class Sample4

{

public native MailInfo[] objectMethod(String text);

public static void main(String[] args)

{

System.loadLibrary("Sample4");

Sample4 sample = new Sample4();

MailInfo[] mails = sample.objectMethod("Thinking In Java");

for(int i=0;i

System.out.println(mails[i].topic);

}

}

Sample4.java调用libSample4.so中的objectMethod()函数。Sample4.c的源代码如下。

代码清单15-14 在Linux平台上调用C函数的例程——Sample4.c

#include

#include

#include

#define ARRAY_LENGTH 5

JNIEXPORT jobjectArray JNICALL Java_Sample4_objectMethod(JNIEnv *env, jobject obj, jstring string)

{

jclass objClass = (*env)->FindClass(env, "java/lang/Object");

jobjectArray mails= (*env)->NewObjectArray(env, (jsize)ARRAY_LENGTH, objClass, 0);


jclass objectClass = (*env)->FindClass(env, "MailInfo");

jfieldID topicFieldId = (*env)->GetFieldID(env, objectClass, "topic", "Ljava/lang/String;");


int i=0;

for(;i

{

(*env)->SetObjectField(env, obj, topicFieldId, string);

(*env)->SetObjectArrayElement(env, mails, i, obj);

}


return mails;

}

程序的第9、10行读者们应该不会陌生,在上一节的例 程中已经出现过,不同之处在于这次通过FindClass()函数在JNI上下文中获取的是java.lang.