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.传递对象数组 MailInfo对象定义如下。 代码清单15-12 在Linux平台上调用C函数的例程——MailInfo public class MailInfo { public String topic; public String getTopic() { return this.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); jfieldID topicFieldId = (*env)->GetFieldID(env, objectClass, "topic", "Ljava/lang/String;"); for(;i { (*env)->SetObjectField(env, obj, topicFieldId, string); (*env)->SetObjectArrayElement(env, mails, i, obj); } } 程序的第9、10行读者们应该不会陌生,在上一节的例 程中已经出现过,不同之处在于这次通过FindClass()函数在JNI上下文中获取的是java.lang.
本节例程演示的是C程序向Java程序传递对象数组,而且对象数组中存放的不再是字符串,而是一个在Java中自定义的、含有一个topic属性的MailInfo对象类型。
public void setTopic(String topic)
jclass objectClass = (*env)->FindClass(env, "MailInfo");
int i=0;
return mails;