Java JNI由浅入深(包括:Java和C++互传ArrayList泛型对象参数)

Java JNI由浅入深(包括:Java和C++互传ArrayList泛型对象参数) 
2010-11-25 09:57 1168人阅读 评论(1) 收藏 举报 



         我们知道Java是一个运行在虚拟机里面的高级的编程语言,如果要调用系统的动态链接库的话,就要先声明native修饰的方法(类似接口里面的方法),再由C/C++程序来实现(类似实现接口里的方法)。这样Java调用这些native方法就相当于调用了C/C++里面实现了的方法。通常我们把这种机制叫做JNI(Java NativeInterfac),即Java 本地编程接口 


          Android也同理,要学会在Android上进行NDK开发,首先我们到打好java JNI的基础。现在我们暂时把Android开发丢到一边先,试试在Java之下编译一个C动态链接库,再用Java程序调用。 



1)先来个最简单的打印HelloWorld例子: 

Java代码(HelloJni.java): 

view plainprint? 

   1. import java.util.*;  
   2. public class HelloJni{  
   3.       
   4.     static{  
   5.         System.loadLibrary("hello");  
   6.     }  
   7.     public native static void sayHello();  
   8.     public static void main(String [] args)  
   9.     {  
  10.                 HelloJni.sayHello();  
  11.     }  
  12. }  

import java.util.*; public class HelloJni{ static{ System.loadLibrary("hello"); } public native static void sayHello(); public static void main(String [] args) { HelloJni.sayHello(); } }  

生成头文件(HelloJni.h): 

先javac HelloJni.java编译你的Java源码,再javah–jni HelloJni生成所需的头文件 

头文件内容是这样的: 

view plainprint? 

   1. /* DO NOT EDIT THIS FILE - it is machine generated */  
   2. #include <jni.h>  
   3. /* Header for class HelloJni */  
   4. #ifndef _Included_HelloJni  
   5. #define _Included_HelloJni  
   6. #ifdef __cplusplus  
   7. extern "C" {  
   8. #endif  
   9. JNIEXPORT void JNICALL Java_HelloJni_sayHello (JNIEnv *, jclass);  
  10. #ifdef __cplusplus  
  11. }  
  12. #endif  
  13. #endif  

/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class HelloJni */ #ifndef _Included_HelloJni #define _Included_HelloJni #ifdef __cplusplus extern "C" { #endif JNIEXPORT void JNICALL Java_HelloJni_sayHello (JNIEnv *, jclass); #ifdef __cplusplus } #endif #endif 


实现头文件声明的方法(HelloJni.cpp) 


view plainprint? 

   1. #include "HelloJni.h"  
   2. JNIEXPORT void JNICALL Java_HelloJni_sayHello(JNIEnv *env, jclass cls)  
   3. {  
   4.        printf("HelloWorld");  
   5. }  

#include "HelloJni.h" JNIEXPORT void JNICALL Java_HelloJni_sayHello(JNIEnv *env, jclass cls) { printf("HelloWorld"); } 



编译命令: g++ -I$JAVA_HOME/include-I$JAVA_HOME/include/linux HelloJni.cpp -shared -o libhello.so 

命令参数解析:-I 是指引入java虚拟机的库的路径,-shared 是指编译成动态链接库(共享库) –o 输出文件名(注意,在Linux平台下的动态链接库有一个命名格式:“lib+库名+.so”在java代码里面loadLibrary的时候不要加lib前缀和.so后缀) 

由于我这里把这个动态链接库编译放在当前目录下,所以还要设置环境变量LD_LIBRARY_PATH=该so动态链接库所在的目录,才能正常运行 



#############################+++华丽的分割线+++########################### 


2)好了,可以打印HelloWorld出来后,我们再深入一点点,传入一个int的数,在C/C++代码里面加1后返回。 



Java代码(HelloJni.java): 

view plainprint? 

   1. public class HelloJni{  
   2.         static{  
   3.                    System.loadLibrary("hello");  
   4.         }  
   5.         public static native void sayHello();  
   6.         public native int getInt();  
   7.         public native void setInt(int i);  
   8.         public static void main(String args[]){  
   9.         //      HelloJni.sayHello();  
  10.                  HelloJni hello = new HelloJni();  
  11.                  hello.setInt(2);  
  12.                  System.out.println(hello.getInt());  
  13.         }  
  14. }  

public class HelloJni{ static{ System.loadLibrary("hello"); } public static native void sayHello(); public native int getInt(); public native void setInt(int i); public static void main(String args[]){ // HelloJni.sayHello(); HelloJni hello = new HelloJni(); hello.setInt(2); System.out.println(hello.getInt()); } } 

生成头文件(HelloJni.h): 

view plainprint? 

   1. /* DO NOT EDIT THIS FILE - it is machine generated */  
   2. #include <jni.h>  
   3. /* Header for class HelloJni */  
   4. #ifndef _Included_HelloJni  
   5. #define _Included_HelloJni  
   6. #ifdef __cplusplus  
   7. extern "C" {  
   8. #endif  
   9. JNIEXPORT void JNICALL Java_HelloJni_sayHello (JNIEnv *, jclass);  
  10. JNIEXPORT jint JNICALL Java_HelloJni_getInt (JNIEnv *, jobject);  
  11. JNIEXPORT void JNICALL Java_HelloJni_setInt (JNIEnv *, jobject, jint);  
  12. #ifdef __cplusplus  
  13. }  
  14. #endif  
  15. #endif  

/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class HelloJni */ #ifndef _Included_HelloJni #define _Included_HelloJni #ifdef __cplusplus extern "C" { #endif JNIEXPORT void JNICALL Java_HelloJni_sayHello (JNIEnv *, jclass); JNIEXPORT jint JNICALL Java_HelloJni_getInt (JNIEnv *, jobject); JNIEXPORT void JNICALL Java_HelloJni_setInt (JNIEnv *, jobject, jint); #ifdef __cplusplus } #endif #endif 

实现头文件声明的方法(HelloJni.cpp) 

view plainprint? 

   1. #include "HelloJni.h"  
   2. int i=1;  
   3. JNIEXPORT void JNICALL Java_HelloJni_sayHello  
   4.   (JNIEnv *env, jclass cls){  
   5.         printf("HelloWorld/n");  
   6. }  
   7. JNIEXPORT jint JNICALL Java_HelloJni_getInt  
   8.   (JNIEnv *env, jobject thiz){  
   9.         return i;  
  10. }  
  11. JNIEXPORT void JNICALL Java_HelloJni_setInt  
  12.   (JNIEnv *env, jobject thiz,jint ji){  
  13.         i = ji+1;  
  14. }  

#include "HelloJni.h" int i=1; JNIEXPORT void JNICALL Java_HelloJni_sayHello (JNIEnv *env, jclass cls){ printf("HelloWorld/n"); } JNIEXPORT jint JNICALL Java_HelloJni_getInt (JNIEnv *env, jobject thiz){ return i; } JNIEXPORT void JNICALL Java_HelloJni_setInt (JNIEnv *env, jobject thiz,jint ji){ i = ji+1; } 

运行结果:打印2 


3)只是传入简单的数据类型不爽,这次让C/C++生成个Java对象返回 



Java代码:pojo实体类(User.java) 

view plainprint? 

   1. public class User{  
   2.         private long id;  
   3.         private String userName;  
   4.         private boolean isMan;  
   5.         private int age;  
   6.         public User(){}  
   7.         public User(long id, String userName, boolean isMan, int age) {  
   8.                 super();  
   9.                 this.id = id;  
  10.                 this.userName = userName;  
  11.                 this.isMan = isMan;  
  12.                 this.age = age;  
  13.         }  
  14.         public long getId() {  
  15.                 return id;  
  16.         }  
  17.         public void setId(long id) {  
  18.                 this.id = id;  
  19.         }  
  20.         public String getUserName() {  
  21.                 return userName;  
  22.         }  
  23.         public void setUserName(String userName) {  
  24.                 this.userName = userName;  
  25.         }  
  26.         public boolean isMan() {  
  27.                 return isMan;  
  28.         }  
  29.         public void setMan(boolean isMan) {  
  30.                 this.isMan = isMan;  
  31.         }  
  32.         public int getAge() {  
  33.                 return age;  
  34.         }  
  35.         public void setAge(int age) {  
  36.                 this.age = age;  
  37.         }  
  38. }  

public class User{ private long id; private String userName; private boolean isMan; private int age; public User(){} public User(long id, String userName, boolean isMan, int age) { super(); this.id = id; this.userName = userName; this.isMan = isMan; this.age = age; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public boolean isMan() { return isMan; } public void setMan(boolean isMan) { this.isMan = isMan; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } 

Java代码(HelloJni.java): 

view plainprint? 

   1. public class HelloJni{  
   2.         static{  
   3.                 System.loadLibrary("userbean");  
   4.         }  
   5.         public static native void sayHello();  
   6.         public native int getInt();  
   7.         public native void setInt(int i);  
   8.         public native void setUser(String userName);  
   9.         public native User getUser();  
  10.         public static void main(String args[]){  
  11.         //      HelloJni.sayHello();  
  12.                 HelloJni hello = new HelloJni();  
  13.         //      hello.setInt(2);  
  14.         //      System.out.println(hello.getInt());  
  15.                 hello.setUser("LiangYaotian");  
  16.                 User user = hello.getUser();  
  17.                 System.out.println("user from c/c++");  
  18.                 System.out.println("name:"+user.getUserName());  
  19.                 System.out.println("isMan?:"+user.isMan());  
  20.                 System.out.println("age:"+user.getAge());  
  21.         }  
  22. }  

public class HelloJni{ static{ System.loadLibrary("userbean"); } public static native void sayHello(); public native int getInt(); public native void setInt(int i); public native void setUser(String userName); public native User getUser(); public static void main(String args[]){ // HelloJni.sayHello(); HelloJni hello = new HelloJni(); // hello.setInt(2); // System.out.println(hello.getInt()); hello.setUser("LiangYaotian"); User user = hello.getUser(); System.out.println("user from c/c++"); System.out.println("name:"+user.getUserName()); System.out.println("isMan?:"+user.isMan()); System.out.println("age:"+user.getAge()); } } 

生成头文件(HelloJni.h): 

view plainprint? 

   1. #include <jni.h>  
   2. /* Header for class HelloJni */  
   3. #ifndef _Included_HelloJni  
   4. #define _Included_HelloJni  
   5. #ifdef __cplusplus  
   6. extern "C" {  
   7. #endif  
   8. JNIEXPORT void JNICALL Java_HelloJni_sayHello (JNIEnv *, jclass);  
   9. JNIEXPORT jint JNICALL Java_HelloJni_getInt (JNIEnv *, jobject);  
  10. JNIEXPORT void JNICALL Java_HelloJni_setInt (JNIEnv *, jobject, jint);  
  11. JNIEXPORT void JNICALL Java_HelloJni_setUser (JNIEnv *, jobject, jstring);  
  12. JNIEXPORT jobject JNICALL Java_HelloJni_getUser  (JNIEnv *, jobject);  
  13. #ifdef __cplusplus  
  14. }  
  15. #endif  
  16. #endif  

#include <jni.h> /* Header for class HelloJni */ #ifndef _Included_HelloJni #define _Included_HelloJni #ifdef __cplusplus extern "C" { #endif JNIEXPORT void JNICALL Java_HelloJni_sayHello (JNIEnv *, jclass); JNIEXPORT jint JNICALL Java_HelloJni_getInt (JNIEnv *, jobject); JNIEXPORT void JNICALL Java_HelloJni_setInt (JNIEnv *, jobject, jint); JNIEXPORT void JNICALL Java_HelloJni_setUser (JNIEnv *, jobject, jstring); JNIEXPORT jobject JNICALL Java_HelloJni_getUser (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif 

实现头文件声明的方法(HelloJni.cpp) 

view plainprint? 

   1. #include <iostream>  
   2. #include <stdio.h>  
   3. using namespace std;  
   4. int i=1;  
   5. jobject user;  
   6. JNIEXPORT void JNICALL Java_HelloJni_sayHello  
   7.   (JNIEnv *env, jclass cls){  
   8.         printf("HelloWorld/n");  
   9. }  
  10. JNIEXPORT jint JNICALL Java_HelloJni_getInt  
  11.   (JNIEnv *env, jobject thiz){  
  12.         return i;  
  13. }  
  14. JNIEXPORT void JNICALL Java_HelloJni_setInt  
  15.   (JNIEnv *env, jobject thiz,jint ji){  
  16.         i = ji+1;  
  17. }  
  18. JNIEXPORT void JNICALL Java_HelloJni_setUser  
  19.   (JNIEnv *env, jobject thiz, jstring name){  
  20.         jclass userClass = env->FindClass("User");  
  21.         jmethodID userMethod = env->GetMethodID(userClass,"<init>","()V");  
  22.         jfieldID mId = env->GetFieldID(userClass,"id","J");  
  23.         jfieldID mUserName = env->GetFieldID(userClass,"userName","Ljava/lang/String;");  
  24.         jfieldID mIsMan = env->GetFieldID(userClass,"isMan","Z");  
  25.         jfieldID mAge = env->GetFieldID(userClass,"age","I");  
  26.         jobject userObject = env->NewObject(userClass,userMethod);  
  27.         env->SetObjectField(userObject,mUserName,name);  
  28.         env->SetLongField(userObject,mId,1001);  
  29.         env->SetBooleanField(userObject,mIsMan,1);  
  30.         env->SetIntField(userObject,mAge,21);  
  31.         user = userObject;  
  32. }  

#include <iostream> #include <stdio.h> using namespace std; int i=1; jobject user; JNIEXPORT void JNICALL Java_HelloJni_sayHello (JNIEnv *env, jclass cls){ printf("HelloWorld/n"); } JNIEXPORT jint JNICALL Java_HelloJni_getInt (JNIEnv *env, jobject thiz){ return i; } JNIEXPORT void JNICALL Java_HelloJni_setInt (JNIEnv *env, jobject thiz,jint ji){ i = ji+1; } JNIEXPORT void JNICALL Java_HelloJni_setUser (JNIEnv *env, jobject thiz, jstring name){ jclass userClass = env->FindClass("User"); jmethodID userMethod = env->GetMethodID(userClass,"<init>","()V"); jfieldID mId = env->GetFieldID(userClass,"id","J"); jfieldID mUserName = env->GetFieldID(userClass,"userName","Ljava/lang/String;"); jfieldID mIsMan = env->GetFieldID(userClass,"isMan","Z"); jfieldID mAge = env->GetFieldID(userClass,"age","I"); jobject userObject = env->NewObject(userClass,userMethod); env->SetObjectField(userObject,mUserName,name); env->SetLongField(userObject,mId,1001); env->SetBooleanField(userObject,mIsMan,1); env->SetIntField(userObject,mAge,21); user = userObject; } 





4)有些同学可能会说:“返回个Java对象算什么啊,C/C++和Java之间互传复杂对象才好玩呢!”正所谓“不怕做不到,就怕想不到”,我们接着重构一下上面那个例子! 


这次我们传包含有User对象的List到C/C++程序里面 


Java代码(User.java) 

同上。 

Java代码(HelloJni.java) 

view plainprint? 

   1. import java.util.*;  
   2. public class HelloJni{  
   3.         static{  
   4.                 System.loadLibrary("userbean");  
   5.         }  
   6.         public native int get();  
   7.         public native void set(int i);  
   8.         public native void setUser(String userName);  
   9.         public native User getUser();  
  10.         public native void setUserList(ArrayList<User> userList);  
  11.         public native ArrayList<User> getUserList();  
  12.         public static void main(String [] args)  
  13.         {  
  14.                 HelloJni hello = new HelloJni();  
  15.         //      hello.set(2);  
  16.         //      System.out.println(hello.get());  
  17.         /* 
  18.                 hello.setUser("LiangYaotian"); 
  19.                 User user = hello.getUser(); 
  20.                 System.out.println("user from c/c++"); 
  21.                 System.out.println("name:"+user.getUserName()); 
  22.                 System.out.println("isMan?:"+user.isMan()); 
  23.                 System.out.println("age:"+user.getAge()); 
  24.         */  
  25.                 ArrayList<User> userList = new ArrayList<User>();  
  26.                 for(int i=0;i<10;i++){  
  27.                         User u = new User((long)(1000+i),"LiangYaotian"+i,true,21);  
  28.                         userList.add(u);  
  29.                 }  
  30.                 hello.setUserList(userList);  
  31.                 userList = null;  
  32.                 userList = hello.getUserList();  
  33.                 System.out.println("ArrayList<User> construct from C++,then Java print it.....");  
  34.                 for(User u : userList){  
  35.                         System.out.println("id:"+u.getId()+"; name:"+u.getUserName());  
  36.                 }  
  37.         }  
  38. }  

import java.util.*; public class HelloJni{ static{ System.loadLibrary("userbean"); } public native int get(); public native void set(int i); public native void setUser(String userName); public native User getUser(); public native void setUserList(ArrayList<User> userList); public native ArrayList<User> getUserList(); public static void main(String [] args) { HelloJni hello = new HelloJni(); // hello.set(2); // System.out.println(hello.get()); /* hello.setUser("LiangYaotian"); User user = hello.getUser(); System.out.println("user from c/c++"); System.out.println("name:"+user.getUserName()); System.out.println("isMan?:"+user.isMan()); System.out.println("age:"+user.getAge()); */ ArrayList<User> userList = new ArrayList<User>(); for(int i=0;i<10;i++){ User u = new User((long)(1000+i),"LiangYaotian"+i,true,21); userList.add(u); } hello.setUserList(userList); userList = null; userList = hello.getUserList(); System.out.println("ArrayList<User> construct from C++,then Java print it....."); for(User u : userList){ System.out.println("id:"+u.getId()+"; name:"+u.getUserName()); } } } 

C头文件(HelloJni.h) 

view plainprint? 

   1. #include <jni.h>  
   2. /* Header for class HelloJni */  
   3. #ifndef _Included_HelloJni  
   4. #define _Included_HelloJni  
   5. #ifdef __cplusplus  
   6. extern "C" {  
   7. #endif  
   8. JNIEXPORT void JNICALL Java_HelloJni_sayHello (JNIEnv *, jclass);  
   9. JNIEXPORT jint JNICALL Java_HelloJni_getInt (JNIEnv *, jobject);  
  10. JNIEXPORT void JNICALL Java_HelloJni_setInt (JNIEnv *, jobject, jint);  
  11. JNIEXPORT void JNICALL Java_HelloJni_setUser (JNIEnv *, jobject, jstring);  
  12. JNIEXPORT jobject JNICALL Java_HelloJni_getUser  (JNIEnv *, jobject);  

#include <jni.h> /* Header for class HelloJni */ #ifndef _Included_HelloJni #define _Included_HelloJni #ifdef __cplusplus extern "C" { #endif JNIEXPORT void JNICALL Java_HelloJni_sayHello (JNIEnv *, jclass); JNIEXPORT jint JNICALL Java_HelloJni_getInt (JNIEnv *, jobject); JNIEXPORT void JNICALL Java_HelloJni_setInt (JNIEnv *, jobject, jint); JNIEXPORT void JNICALL Java_HelloJni_setUser (JNIEnv *, jobject, jstring); JNIEXPORT jobject JNICALL Java_HelloJni_getUser (JNIEnv *, jobject); 

头文件的实现(HelloJni.cpp) 

view plainprint? 

   1. #include "HelloJni.h"  
   2. int i=1;  
   3. jobject user;  
   4. JNIEXPORT jint JNICALL Java_HelloJni_get  
   5.   (JNIEnv *env, jobject jthiz){  
   6.         printf("HelloWorld/n");  
   7. }  
   8. JNIEXPORT void JNICALL Java_HelloJni_set  
   9.   (JNIEnv *env, jobject jthiz, jint ji){  
  10.         i = ji+1;  
  11. }  
  12. JNIEXPORT void JNICALL Java_HelloJni_setUser  
  13.   (JNIEnv *env, jobject jthiz, jstring name){  
  14.         jclass userClass = env->FindClass("User");  
  15.         jmethodID userMethod = env->GetMethodID(userClass,"<init>","()V");  
  16.         jfieldID mId = env->GetFieldID(userClass,"id","J");  
  17.         jfieldID mUserName = env->GetFieldID(userClass,"userName","Ljava/lang/String;");  
  18.         jfieldID mIsMan = env->GetFieldID(userClass,"isMan","Z");  
  19.         jfieldID mAge = env->GetFieldID(userClass,"age","I");  
  20.         jobject userObject = env->NewObject(userClass,userMethod);  
  21.         env->SetObjectField(userObject,mUserName,name);  
  22.         env->SetLongField(userObject,mId,1001);  
  23.         env->SetBooleanField(userObject,mIsMan,1);  
  24.         env->SetIntField(userObject,mAge,21);  
  25.         user = userObject;  
  26. }  
  27. JNIEXPORT jobject JNICALL Java_HelloJni_getUser  
  28.   (JNIEnv *env, jobject jthiz){  
  29.         return user;  
  30. }  
  31. JNIEXPORT void JNICALL Java_HelloJni_setUserList  
  32.   (JNIEnv *env, jobject jthiz, jobject userList){  
  33.         int i;  
  34.         //class ArrayList  
  35.         jclass cls_arraylist = env->GetObjectClass(userList);  
  36.         //method in class ArrayList  
  37.         jmethodID arraylist_get = env->GetMethodID(cls_arraylist,"get","(I)Ljava/lang/Object;");  
  38.         jmethodID arraylist_size = env->GetMethodID(cls_arraylist,"size","()I");  
  39.         jint len = env->CallIntMethod(userList,arraylist_size);  
  40.         printf("get java ArrayList<User> object by C++ , then print it...../n");  
  41.         for(i=0;i<len;i++){  
  42.                 jobject obj_user = env->CallObjectMethod(userList,arraylist_get,i);  
  43.                 jclass cls_user = env->GetObjectClass(obj_user);  
  44.                 jmethodID user_getId = env->GetMethodID(cls_user,"getId","()J");  
  45.                 jmethodID user_getUserName = env->GetMethodID(cls_user,"getUserName","()Ljava/lang/String;");  
  46.                 jmethodID user_isMan = env->GetMethodID(cls_user,"isMan","()Z");  
  47.                 jmethodID user_getAge = env->GetMethodID(cls_user,"getAge","()I");  
  48.                 jstring name = (jstring)env->CallObjectMethod(obj_user,user_getUserName);  
  49.                 jboolean b = true;  
  50.                 const char *namePtr = env->GetStringUTFChars(name,&b);  
  51.                 jlong id = env->CallLongMethod(obj_user,user_getId);  
  52.                 jboolean sex = env->CallBooleanMethod(obj_user,user_isMan);  
  53.                 jint age = env->CallIntMethod(obj_user,user_getAge);  
  54.                 printf("Id:%d; ",id);  
  55.                 printf("Name:%s; ",namePtr);  
  56.                 printf("isMan? %d; ",sex);  
  57.                 printf("Age:%d /n ",age);  
  58.         }  
  59. }  
  60. JNIEXPORT jobject JNICALL Java_HelloJni_getUserList  
  61.   (JNIEnv *env, jobject jthiz){  
  62.         //ArrayList Object  
  63.         jclass cls_ArrayList = env->FindClass("java/util/ArrayList");  
  64.         jmethodID construct = env->GetMethodID(cls_ArrayList,"<init>","()V");  
  65.         jobject obj_ArrayList = env->NewObject(cls_ArrayList,construct,"");  
  66.         jmethodID arrayList_add = env->GetMethodID(cls_ArrayList,"add","(Ljava/lang/Object;)Z");  
  67.         //User Object  
  68.         jclass cls_user = env->FindClass("User");  
  69.         //none argument construct function  
  70.         jmethodID construct_user = env->GetMethodID(cls_user,"<init>","()V");  
  71.         //new a object  
  72.         jobject obj_user = env->NewObject(cls_user,construct_user,"");  
  73.         //get method id  
  74.         /* 
  75.         jmethodID user_setId = env->GetMethodID(cls_user,"setId","(J)V"); 
  76.         jmethodID user_setUserName = env->GetMethodID(cls_user,"setUserName","(Ljava/lang/String;)V"); 
  77.         jmethodID user_setMan = env->GetMethodID(cls_user,"setMan","(Z)V"); 
  78.         jmethodID user_setAge = env->GetMethodID(cls_user,"setAge","(I)V"); 
  79.         */  
  80.         int i;  
  81.         for(i=0;i<10;i++){  
  82.         //new a object  
  83.         jobject obj_user = env->NewObject(cls_user,construct_user,"");  
  84.         //get field id  
  85.         jfieldID user_id = env->GetFieldID(cls_user,"id","J");  
  86.         jfieldID user_name = env->GetFieldID(cls_user,"userName","Ljava/lang/String;");  
  87.         jfieldID user_isMan = env->GetFieldID(cls_user,"isMan","Z");  
  88.         jfieldID user_age = env->GetFieldID(cls_user,"age","I");  
  89.         env->SetLongField(obj_user,user_id,i);  
  90.         env->SetObjectField(obj_user,user_name,env->NewStringUTF("LiangYaoTian"));  
  91.         env->SetBooleanField(obj_user,user_isMan,1);  
  92.         env->SetIntField(obj_user,user_age,21);  
  93.                 env->CallObjectMethod(obj_ArrayList,arrayList_add,obj_user);  
  94.         }  
  95.         return obj_ArrayList;  
  96. }  

#include "HelloJni.h" int i=1; jobject user; JNIEXPORT jint JNICALL Java_HelloJni_get (JNIEnv *env, jobject jthiz){ printf("HelloWorld/n"); } JNIEXPORT void JNICALL Java_HelloJni_set (JNIEnv *env, jobject jthiz, jint ji){ i = ji+1; } JNIEXPORT void JNICALL Java_HelloJni_setUser (JNIEnv *env, jobject jthiz, jstring name){ jclass userClass = env->FindClass("User"); jmethodID userMethod = env->GetMethodID(userClass,"<init>","()V"); jfieldID mId = env->GetFieldID(userClass,"id","J"); jfieldID mUserName = env->GetFieldID(userClass,"userName","Ljava/lang/String;"); jfieldID mIsMan = env->GetFieldID(userClass,"isMan","Z"); jfieldID mAge = env->GetFieldID(userClass,"age","I"); jobject userObject = env->NewObject(userClass,userMethod); env->SetObjectField(userObject,mUserName,name); env->SetLongField(userObject,mId,1001); env->SetBooleanField(userObject,mIsMan,1); env->SetIntField(userObject,mAge,21); user = userObject; } JNIEXPORT jobject JNICALL Java_HelloJni_getUser (JNIEnv *env, jobject jthiz){ return user; } JNIEXPORT void JNICALL Java_HelloJni_setUserList (JNIEnv *env, jobject jthiz, jobject userList){ int i; //class ArrayList jclass cls_arraylist = env->GetObjectClass(userList); //method in class ArrayList jmethodID arraylist_get = env->GetMethodID(cls_arraylist,"get","(I)Ljava/lang/Object;"); jmethodID arraylist_size = env->GetMethodID(cls_arraylist,"size","()I"); jint len = env->CallIntMethod(userList,arraylist_size); printf("get java ArrayList<User> object by C++ , then print it...../n"); for(i=0;i<len;i++){ jobject obj_user = env->CallObjectMethod(userList,arraylist_get,i); jclass cls_user = env->GetObjectClass(obj_user); jmethodID user_getId = env->GetMethodID(cls_user,"getId","()J"); jmethodID user_getUserName = env->GetMethodID(cls_user,"getUserName","()Ljava/lang/String;"); jmethodID user_isMan = env->GetMethodID(cls_user,"isMan","()Z"); jmethodID user_getAge = env->GetMethodID(cls_user,"getAge","()I"); jstring name = (jstring)env->CallObjectMethod(obj_user,user_getUserName); jboolean b = true; const char *namePtr = env->GetStringUTFChars(name,&b); jlong id = env->CallLongMethod(obj_user,user_getId); jboolean sex = env->CallBooleanMethod(obj_user,user_isMan); jint age = env->CallIntMethod(obj_user,user_getAge); printf("Id:%d; ",id); printf("Name:%s; ",namePtr); printf("isMan? %d; ",sex); printf("Age:%d /n ",age); } } JNIEXPORT jobject JNICALL Java_HelloJni_getUserList (JNIEnv *env, jobject jthiz){ //ArrayList Object jclass cls_ArrayList = env->FindClass("java/util/ArrayList"); jmethodID construct = env->GetMethodID(cls_ArrayList,"<init>","()V"); jobject obj_ArrayList = env->NewObject(cls_ArrayList,construct,""); jmethodID arrayList_add = env->GetMethodID(cls_ArrayList,"add","(Ljava/lang/Object;)Z"); //User Object jclass cls_user = env->FindClass("User"); //none argument construct function jmethodID construct_user = env->GetMethodID(cls_user,"<init>","()V"); //new a object jobject obj_user = env->NewObject(cls_user,construct_user,""); //get method id /* jmethodID user_setId = env->GetMethodID(cls_user,"setId","(J)V"); jmethodID user_setUserName = env->GetMethodID(cls_user,"setUserName","(Ljava/lang/String;)V"); jmethodID user_setMan = env->GetMethodID(cls_user,"setMan","(Z)V"); jmethodID user_setAge = env->GetMethodID(cls_user,"setAge","(I)V"); */ int i; for(i=0;i<10;i++){ //new a object jobject obj_user = env->NewObject(cls_user,construct_user,""); //get field id jfieldID user_id = env->GetFieldID(cls_user,"id","J"); jfieldID user_name = env->GetFieldID(cls_user,"userName","Ljava/lang/String;"); jfieldID user_isMan = env->GetFieldID(cls_user,"isMan","Z"); jfieldID user_age = env->GetFieldID(cls_user,"age","I"); env->SetLongField(obj_user,user_id,i); env->SetObjectField(obj_user,user_name,env->NewStringUTF("LiangYaoTian")); env->SetBooleanField(obj_user,user_isMan,1); env->SetIntField(obj_user,user_age,21); env->CallObjectMethod(obj_ArrayList,arrayList_add,obj_user); } return obj_ArrayList; } 

运行结果: 

theEnd.jpg 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值