`
anson_xu
  • 浏览: 514570 次
  • 性别: Icon_minigender_1
  • 来自: 惠州
社区版块
存档分类

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





源码:E-Mail我:u_xtian@qq.com

原创作品,转载需注明出处...http://blog.csdn.net/u_xtian/archive/2010/11/25/6033963.aspx
分享到:
评论

相关推荐

    Java通过JNI和c++对象互传

    "Java通过JNI和C++对象互传" Java Native Interface(JNI)是一种允许Java代码和native代码之间进行交互的机制。JNI提供了一种方式,使得Java代码可以调用native代码,而native代码也可以调用Java代码。在这个示例...

    jni操作arraylist对象

    3. **创建int类型的Java对象**:由于ArrayList的`add`方法期望一个Object参数,我们需要将int值转换为Integer对象。为此,我们需要使用`env-&gt;NewObject`方法创建一个Integer对象。 ```c++ jclass integerClass = ...

    JNI学习二:字符串参数传递与返回值

    在本示例中,我们关注的是JNI中的字符串参数传递和返回值处理,这对于那些需要在Java和C/C++之间进行深度集成的项目非常重要。 1. **JNI基本概念** JNI是Java平台提供的一个接口,它使得开发者可以编写本地方法...

    JNI与C++数据类型传递示例(包括ArrayList对象、ArrayList嵌套返回)

    一个C++(Ubuntu16.04+QT5.9.1)通过JNI,调用JAVA类及方法的示例。通过JNI传递和返回多种类型的参数,boolean ,int,String,ArrayList,ArrayList嵌套ArrayList&lt;ArrayList&lt;String&gt;&gt;等。

    C++库封装JNI接口-实现java调用c++

    在跨平台的软件开发中,有时我们需要...这个过程需要理解Java和C++之间的数据类型转换,以及如何在两种语言之间传递参数和返回值。熟练掌握JNI可以极大地扩展Java应用的功能,尤其是在需要高性能计算或利用硬件特性时。

    jni.rar_JNI编程_java jni_jni_site:www.pudn.com

    JNI(Java Native Interface)是Java平台提供的一种标准接口,它允许Java代码和其他语言写的代码进行交互,特别是C和C++。JNI在很多场景下都扮演着重要的角色,比如提升性能、利用现有C/C++库、操作系统级别的交互等...

    Jni中C++和Java的参数传递

    在JNI中,我们可以使用C++或C语言编写本地方法,这些本地方法可以直接访问和操作Java对象,包括传递参数和接收返回值。在涉及到C++和Java之间的参数传递时,有一些特定的规则和技巧需要注意。 首先,我们要理解Java...

    JNI开发Java和C/C++互相传递List集合

    JNI开发Java和C/C++互相传递List集合, 可以参考: Java从C/C++获取List集合对象:https://blog.csdn.net/niuba123456/article/details/80994166 Java传递List集合对象到C/C++ ...

    JNI DEMO:java jni技术 调用 c/c++ 的dll

    JNI(Java Native Interface)是Java平台的标准组成部分,它允许Java代码和其他语言写的代码进行交互。JNI在许多场景下非常有用,比如当需要调用已有的C/C++库或者需要利用硬件特性时。在这个"JNI DEMO"中,我们将...

    java jni c++代码

    3. **JNI函数**: 例如`FindClass`, `GetMethodID`, `NewObject`等,用于在C/C++中操作Java对象和类。 4. **JNI环境**: 一个结构体指针,包含了执行本地方法所需的所有上下文信息。 在Visual Studio 2010中开发JNI...

    JNI:Java与C++的美好结合 视频地址

    JNI,全称Java Native Interface,是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互。JNI在很多场景下都是必要的,比如当需要利用已有的C或C++库、提高性能、或者接入操作系统特定的功能时。在这...

    JAVA JNI C++调用示例

    在这个过程中,关键点包括正确地处理JNI数据类型,如 `jobject`、`JNIEnv *` 和 `jmethodID`,以及在C++中调用Java方法。JNI提供了一套API来实现这些功能,例如 `CallVoidMethod()`、`FindClass()` 和 `GetMethodID...

    jni对象获取,使用jni从c++里获取Java对象

    JNI是Java平台标准的一部分,为开发者提供了在本地代码(如C或C++)中调用Java方法和字段,以及创建和操作Java对象的能力。JNI接口包括一组函数,这些函数允许本地代码与Java虚拟机(JVM)进行通信。 2. **注册...

    Android-JNI完整工程,实现c++调用java和java调用c++

    - JNI签名是C/C++函数原型的特殊表示,它包括参数类型和返回类型。例如,对于`void callFromJava()`,其JNI签名是`()V`。 4. **实现JNI方法**: - 在C/C++源文件中,实现生成的头文件中声明的函数,例如: ```...

    jni操作list集合,来存储对象

    - 在C/C++中实现JNI方法,创建和操作Java对象。 - 注意对象序列化和内存管理。 - 处理可能出现的异常。 通过以上步骤,我们可以使用JNI在Android应用中高效地处理Java的List集合,包括存储自定义对象。这在某些需要...

    使用JNI进行混合编程:在Java中调用C/C++本地库

    JNI框架包括了Java端的本地方法声明和本地方法实现,以及C/C++端的头文件和源代码。 1. **Java端的设置**: - 在Java类中,我们需要声明本地方法。例如,`native void callNative();` 这是一个没有参数且返回值为...

    Qt for Android 用JNI来使C++和Java互调(目前最新版全网只有这个可用)

    "Qt for Android 用JNI来使C++和Java互调"的主题揭示了如何利用JNI(Java Native Interface)技术在Qt与Android原生系统之间建立桥梁,实现两者的交互。以下将详细介绍这一过程。 首先,Qt for Android是Qt项目的一...

    JNI 调用实例(java JNI cpp互相调用实例)

    通过本文,我们可以了解 Java 和 C++ 之间的互相调用实例的实现过程,包括 C++ DLL 文件的创建和使用,以及 Java 代码中使用 JNI 技术调用 C++ DLL 文件的实现细节。这种技术可以应用于需要 Java 和 C++ 之间互相...

    JAVA通过JNI调用C#dll的整个项目工程

    JNI接口包括一系列的函数,如`FindClass`, `GetFieldID`, `CallVoidMethod`等,它们用于在Java和本地代码之间建立桥梁。 2. **创建C# DLL**: 在C#环境中,使用Visual Studio或其他开发工具创建一个新的类库项目,...

    使用C++创建java虚拟机JVM,使用JNI调用java函数.zip

    在提供的资源"使用C++创建java虚拟机JVM,使用JNI调用java函数"中,可能详细介绍了以上步骤的实际应用,包括代码示例和可能遇到的问题及解决方案。通过学习和实践这个教程,开发者可以更好地理解和掌握C++与Java之间...

Global site tag (gtag.js) - Google Analytics