- 浏览: 514570 次
- 性别:
- 来自: 惠州
文章分类
- 全部博客 (255)
- ant (1)
- springMVC (2)
- ajax (4)
- oracle (12)
- SSH (13)
- struts1 (2)
- Hibernate (14)
- spring (5)
- jstl (1)
- 连接池 (1)
- acegi (4)
- java (17)
- jquery (11)
- div+css (4)
- drupal (1)
- php (8)
- freemaker调模板生成静态页面 (1)
- xml (1)
- json (2)
- javascript (9)
- 正则表达式 (4)
- Ext (8)
- jdbc (1)
- sql server (2)
- perl (5)
- db4o (1)
- webservice (4)
- flex (13)
- it资讯 (1)
- joomla (0)
- 设计模式 (1)
- struts2 (4)
- s2sh (8)
- linux (3)
- ejb (2)
- android旅途 (24)
- android (36)
- C/C++ (16)
- mysql (1)
最新评论
-
fengyuxing168:
IBelyService bs = IBelyService. ...
为 Android 添加 Java 层服务也就是添加自定义的aidl服务到serviceManager 通过ServiceManager.getService取 -
dengzhangtao:
"由于ActivityManagerService是 ...
binder理解 -
yzyspy:
ActivityManagerService:startHom ...
Android的Launcher成为系统中第一个启动的,也是唯一的 -
Matchstick:
使用SELECT DISTINCT alias FROM Po ...
hibernate 一对多表查询时fetchMode.join 生成left outer join 出来数据重复问题 -
dlheart:
没看懂你什么意思啊,我遇到的问题是一对多,设了fetch = ...
hibernate 一对多表查询时fetchMode.join 生成left outer join 出来数据重复问题
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
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
发表评论
-
Linux内存点滴 用户进程内存空间 stack heap text data
2013-01-19 16:54 2957Linux内存点滴 用户进程内存空间 经常使用top ... -
JNI编程(二) —— 让C++和Java相互调用(1)
2011-10-28 11:55 934自己在外面偷偷的算了下,又有将近两个月没更新过blog了。趁着 ... -
Android jni 常用方法备忘
2011-10-28 10:44 1199Android jni 常用方法备忘 ... -
c 线程同步
2011-10-28 09:23 894#include <pthread.h> #inc ... -
c++ 双线程协议解析 链表 sleep pthread_join g++编译
2011-10-25 11:37 1712主类 testlinklist.cpp #include &l ... -
undefined reference to 'pthread_create'问题解决
2011-10-25 10:19 1291undefined reference to 'pthread ... -
strlen与sizeof的区别
2011-10-12 14:20 844strlen与sizeof的区别 最后一个int a[3 ... -
C/C++语言数组作为参数传递
2011-09-28 17:08 1311#include <stdio.h> #inclu ... -
c/c++字符函数操作
2011-09-20 17:01 850// 取得Xml元素的值 // itemName:元 ... -
C++——指针,堆栈,引用,函数
2011-09-16 14:07 1370C++——指针,堆栈,引用,函数 ... -
今天看了两个小时<<21天学通C++>>把C++中的指针、引用、传值问题弄清楚了
2011-09-16 11:13 1070今天看了两个小时 <<21 天学通 C+ ... -
STL中的"集合类"的定义使用
2011-09-16 09:23 1389STL 中的" 集合类" 的定义 ... -
c++链表操作
2011-09-15 19:22 919最后我学习一下如何在已有的链表上插入节点 我们要考虑四 ... -
c++面向对象的编程入门篇--类构造函数与析构函数
2011-09-15 16:14 979请注意,这一节内容是c++的重点,要特别注意! 我们先说一 ... -
C++实例集合类
2011-09-13 11:04 1288// 此程序通过数组来定义集合类,虽不如链表高级, ... -
C++操作符含义
2011-01-20 10:44 2124C++操作符含义 "->"是 ...
相关推荐
"Java通过JNI和C++对象互传" Java Native Interface(JNI)是一种允许Java代码和native代码之间进行交互的机制。JNI提供了一种方式,使得Java代码可以调用native代码,而native代码也可以调用Java代码。在这个示例...
3. **创建int类型的Java对象**:由于ArrayList的`add`方法期望一个Object参数,我们需要将int值转换为Integer对象。为此,我们需要使用`env->NewObject`方法创建一个Integer对象。 ```c++ jclass integerClass = ...
在本示例中,我们关注的是JNI中的字符串参数传递和返回值处理,这对于那些需要在Java和C/C++之间进行深度集成的项目非常重要。 1. **JNI基本概念** JNI是Java平台提供的一个接口,它使得开发者可以编写本地方法...
一个C++(Ubuntu16.04+QT5.9.1)通过JNI,调用JAVA类及方法的示例。通过JNI传递和返回多种类型的参数,boolean ,int,String,ArrayList,ArrayList嵌套ArrayList<ArrayList<String>>等。
在跨平台的软件开发中,有时我们需要...这个过程需要理解Java和C++之间的数据类型转换,以及如何在两种语言之间传递参数和返回值。熟练掌握JNI可以极大地扩展Java应用的功能,尤其是在需要高性能计算或利用硬件特性时。
JNI(Java Native Interface)是Java平台提供的一种标准接口,它允许Java代码和其他语言写的代码进行交互,特别是C和C++。JNI在很多场景下都扮演着重要的角色,比如提升性能、利用现有C/C++库、操作系统级别的交互等...
在JNI中,我们可以使用C++或C语言编写本地方法,这些本地方法可以直接访问和操作Java对象,包括传递参数和接收返回值。在涉及到C++和Java之间的参数传递时,有一些特定的规则和技巧需要注意。 首先,我们要理解Java...
JNI开发Java和C/C++互相传递List集合, 可以参考: Java从C/C++获取List集合对象:https://blog.csdn.net/niuba123456/article/details/80994166 Java传递List集合对象到C/C++ ...
JNI(Java Native Interface)是Java平台的标准组成部分,它允许Java代码和其他语言写的代码进行交互。JNI在许多场景下非常有用,比如当需要调用已有的C/C++库或者需要利用硬件特性时。在这个"JNI DEMO"中,我们将...
3. **JNI函数**: 例如`FindClass`, `GetMethodID`, `NewObject`等,用于在C/C++中操作Java对象和类。 4. **JNI环境**: 一个结构体指针,包含了执行本地方法所需的所有上下文信息。 在Visual Studio 2010中开发JNI...
JNI,全称Java Native Interface,是Java平台标准的一部分,它允许Java代码和其他语言写的代码进行交互。JNI在很多场景下都是必要的,比如当需要利用已有的C或C++库、提高性能、或者接入操作系统特定的功能时。在这...
在这个过程中,关键点包括正确地处理JNI数据类型,如 `jobject`、`JNIEnv *` 和 `jmethodID`,以及在C++中调用Java方法。JNI提供了一套API来实现这些功能,例如 `CallVoidMethod()`、`FindClass()` 和 `GetMethodID...
JNI是Java平台标准的一部分,为开发者提供了在本地代码(如C或C++)中调用Java方法和字段,以及创建和操作Java对象的能力。JNI接口包括一组函数,这些函数允许本地代码与Java虚拟机(JVM)进行通信。 2. **注册...
- JNI签名是C/C++函数原型的特殊表示,它包括参数类型和返回类型。例如,对于`void callFromJava()`,其JNI签名是`()V`。 4. **实现JNI方法**: - 在C/C++源文件中,实现生成的头文件中声明的函数,例如: ```...
- 在C/C++中实现JNI方法,创建和操作Java对象。 - 注意对象序列化和内存管理。 - 处理可能出现的异常。 通过以上步骤,我们可以使用JNI在Android应用中高效地处理Java的List集合,包括存储自定义对象。这在某些需要...
JNI框架包括了Java端的本地方法声明和本地方法实现,以及C/C++端的头文件和源代码。 1. **Java端的设置**: - 在Java类中,我们需要声明本地方法。例如,`native void callNative();` 这是一个没有参数且返回值为...
"Qt for Android 用JNI来使C++和Java互调"的主题揭示了如何利用JNI(Java Native Interface)技术在Qt与Android原生系统之间建立桥梁,实现两者的交互。以下将详细介绍这一过程。 首先,Qt for Android是Qt项目的一...
通过本文,我们可以了解 Java 和 C++ 之间的互相调用实例的实现过程,包括 C++ DLL 文件的创建和使用,以及 Java 代码中使用 JNI 技术调用 C++ DLL 文件的实现细节。这种技术可以应用于需要 Java 和 C++ 之间互相...
JNI接口包括一系列的函数,如`FindClass`, `GetFieldID`, `CallVoidMethod`等,它们用于在Java和本地代码之间建立桥梁。 2. **创建C# DLL**: 在C#环境中,使用Visual Studio或其他开发工具创建一个新的类库项目,...
在提供的资源"使用C++创建java虚拟机JVM,使用JNI调用java函数"中,可能详细介绍了以上步骤的实际应用,包括代码示例和可能遇到的问题及解决方案。通过学习和实践这个教程,开发者可以更好地理解和掌握C++与Java之间...