JNI小记

本文参考《较详细的介绍JNI》一文,并添加了一些方法,代码已经过测试,留待日后工作使用。关于JNI的HelloWorld的例子,就不赘述了。

java代码:

 1 package com.chnic.service;
 2 
 3 import com.chnic.bean.Order;  
 4 
 5 public class Business {  
 6     static{  
 7         System.loadLibrary("FruitFactory");  
 8     }  
 9       
10     public Business(){  
11           
12     }  
13       
14     public native double getPrice(String name);  
15     public native Order getOrder(String name, int amount);  
16     public native Order getRamdomOrder();  
17     public static native void analyzeOrder(Order order);  
18     
19     public native void showArray(int []nums);
20     
21     public native int[] getIntArray();
22     
23     public native String[] getStringArray(String[] ss);
24     
25     public native void test2DStringArray(String[][] ss);
26       
27     public void notification(){  
28         System.out.println("Got a notification.");  
29     }  
30       
31     public static void notificationByStatic(){  
32         System.out.println("Got a notification in a static method.");  
33     }  
34     
35     public static void main(String...args){
36         Business bus = new Business();
37         System.out.println("price:"+bus.getPrice("Apple"));
38         System.out.println("-------------------------");
39         
40         System.out.println("price:"+bus.getPrice("Pear"));
41         System.out.println("-------------------------");
42         
43         System.out.println(bus.getOrder("Apple",23));
44         System.out.println("-------------------------");
45         
46         System.out.println(bus.getRamdomOrder());
47         System.out.println("-------------------------");
48         
49         Order order = new Order();
50         order.setName("orange");
51         Business.analyzeOrder(order);
52         System.out.println("-------------------------");
53         
54         int[]ia={1,2,3,4};
55         bus.showArray(ia);
56         System.out.println("-------------------------");
57         
58         int[] iaa = bus.getIntArray();
59         for(int i:iaa){
60             System.out.println(i);
61         }
62         System.out.println("-------------------------");
63         
64         String[]abc= {"aa","bb","cc","dd"};
65         bus.getStringArray(abc);
66         System.out.println("-------------------------");
67         
68         String []abcd = bus.getStringArray(abc);
69         for(String s:abcd){
70             System.out.println(s);
71         }
72         System.out.println("-------------------------");
73         
74         String[][]test = {{"一行1号","一行二号","一行三号"},{"二行一号","二行二号","二行三号"}};
75         bus.test2DStringArray(test);
76         System.out.println("-------------------------");
77     }
78 }  
View Code
 1 package com.chnic.bean;
 2 
 3 public class Order {  
 4     
 5     private String name = "Fruit";  
 6     private double price;  
 7     private int amount = 30;  
 8       
 9     public Order(){  
10           
11     }  
12   
13     public int getAmount() {  
14         return amount;  
15     }  
16    
17     public void setAmount(int amount) {  
18         this.amount = amount;  
19     }  
20   
21     public String getName() {  
22         return name;  
23     }  
24   
25     public void setName(String name) {  
26         this.name = name;  
27     }  
28   
29     public double getPrice() {  
30         return price;  
31     }  
32   
33     public void setPrice(double price) {  
34         this.price = price;  
35     }  
36     
37     public String toString(){
38         return "name is "+name+",price is "+price+",amount is "+amount+"."; 
39     }
40 }  
View Code

 

生成的com_chnic_service_Business.h头文件内容如下:

 1 /* DO NOT EDIT THIS FILE - it is machine generated */
 2 #include <jni.h>
 3 /* Header for class com_chnic_service_Business */
 4 
 5 #ifndef _Included_com_chnic_service_Business
 6 #define _Included_com_chnic_service_Business
 7 #ifdef __cplusplus
 8 extern "C" {
 9 #endif
10 /*
11  * Class:     com_chnic_service_Business
12  * Method:    getPrice
13  * Signature: (Ljava/lang/String;)D
14  */
15 JNIEXPORT jdouble JNICALL Java_com_chnic_service_Business_getPrice
16   (JNIEnv *, jobject, jstring);
17 
18 /*
19  * Class:     com_chnic_service_Business
20  * Method:    getOrder
21  * Signature: (Ljava/lang/String;I)Lcom/chnic/bean/Order;
22  */
23 JNIEXPORT jobject JNICALL Java_com_chnic_service_Business_getOrder
24   (JNIEnv *, jobject, jstring, jint);
25 
26 /*
27  * Class:     com_chnic_service_Business
28  * Method:    getRamdomOrder
29  * Signature: ()Lcom/chnic/bean/Order;
30  */
31 JNIEXPORT jobject JNICALL Java_com_chnic_service_Business_getRamdomOrder
32   (JNIEnv *, jobject);
33 
34 /*
35  * Class:     com_chnic_service_Business
36  * Method:    analyzeOrder
37  * Signature: (Lcom/chnic/bean/Order;)V
38  */
39 JNIEXPORT void JNICALL Java_com_chnic_service_Business_analyzeOrder
40   (JNIEnv *, jclass, jobject);
41 
42 /*
43  * Class:     com_chnic_service_Business
44  * Method:    showArray
45  * Signature: ([I)V
46  */
47 JNIEXPORT void JNICALL Java_com_chnic_service_Business_showArray
48   (JNIEnv *, jobject, jintArray);
49 
50 /*
51  * Class:     com_chnic_service_Business
52  * Method:    getIntArray
53  * Signature: ()[I
54  */
55 JNIEXPORT jintArray JNICALL Java_com_chnic_service_Business_getIntArray
56   (JNIEnv *, jobject);
57 
58 /*
59  * Class:     com_chnic_service_Business
60  * Method:    getStringArray
61  * Signature: ([Ljava/lang/String;)[Ljava/lang/String;
62  */
63 JNIEXPORT jobjectArray JNICALL Java_com_chnic_service_Business_getStringArray
64   (JNIEnv *, jobject, jobjectArray);
65 
66 /*
67  * Class:     com_chnic_service_Business
68  * Method:    test2DStringArray
69  * Signature: ([[Ljava/lang/String;)V
70  */
71 JNIEXPORT void JNICALL Java_com_chnic_service_Business_test2DStringArray
72   (JNIEnv *, jobject, jobjectArray);
73 
74 #ifdef __cplusplus
75 }
76 #endif
77 #endif
View Code

 

编写的CPP实现文件(文件名随意),内容如下:

  1 #include <iostream.h>  
  2 #include <string.h>  
  3 #include "com_chnic_service_Business.h"  
  4   
  5 jobject getInstance(JNIEnv* env, jclass obj_class);  
  6 /*
  7  * Class:     com_chnic_service_Business
  8  * Method:    getPrice
  9  * Signature: (Ljava/lang/String;)D
 10  *  传递string参数,返回double值
 11  */
 12 JNIEXPORT jdouble JNICALL Java_com_chnic_service_Business_getPrice(JNIEnv* env,   
 13                                                                    jobject obj,   
 14                                                                    jstring name)  
 15 {  
 16     const char* pname = env->GetStringUTFChars(name, NULL);  
 17     cout << "Before release: "  << pname << endl;  
 18   
 19     if (strcmp(pname, "Apple") == 0)  
 20     {  
 21         env->ReleaseStringUTFChars(name, pname);  
 22         cout << "After release: " << pname << endl;  
 23         return 1.2;  
 24     }   
 25     else  
 26     {  
 27         env->ReleaseStringUTFChars(name, pname);  
 28         cout << "After release: " << pname << endl;  
 29         return 2.1;  
 30     }     
 31 }  
 32   
 33 /*
 34  * Class:     com_chnic_service_Business
 35  * Method:    getOrder
 36  * Signature: (Ljava/lang/String;I)Lcom/chnic/bean/Order;
 37  * 传递string、int参数,回调java类中的方法,并且返回一个java对象
 38  */  
 39 JNIEXPORT jobject JNICALL Java_com_chnic_service_Business_getOrder(JNIEnv* env,   
 40                                                                    jobject obj,   
 41                                                                    jstring name,   
 42                                                                    jint amount)  
 43 {  
 44     jclass order_class = env->FindClass("com/chnic/bean/Order");  
 45     jobject order = getInstance(env, order_class);  
 46       
 47     jmethodID setName_method = env->GetMethodID(order_class, "setName", "(Ljava/lang/String;)V");  
 48     env->CallVoidMethod(order, setName_method, name);  
 49   
 50     jmethodID setAmount_method = env->GetMethodID(order_class, "setAmount", "(I)V");  
 51     env->CallVoidMethod(order, setAmount_method, amount);  
 52   
 53     return order;  
 54 }  
 55   
 56 /*
 57  * Class:     com_chnic_service_Business
 58  * Method:    getRamdomOrder
 59  * Signature: ()Lcom/chnic/bean/Order;
 60  * 无参方法,在C++中构造一个java对象返回
 61  */
 62 JNIEXPORT jobject JNICALL Java_com_chnic_service_Business_getRamdomOrder(JNIEnv* env,   
 63                                                                          jobject obj)  
 64 {  
 65     jclass business_class = env->GetObjectClass(obj);  
 66     jobject business_obj = getInstance(env, business_class);  
 67   
 68     jmethodID notification_method = env->GetMethodID(business_class, "notification", "()V");  
 69     env->CallVoidMethod(obj, notification_method);  
 70   
 71     jclass order_class = env->FindClass("com/chnic/bean/Order");  
 72     jobject order = getInstance(env, order_class);  
 73     jfieldID amount_field = env->GetFieldID(order_class, "amount", "I");  
 74     jint amount = env->GetIntField(order, amount_field);  
 75     cout << "amount: " << amount << endl;  
 76     return order;  
 77 }  
 78   
 79 
 80 /*
 81  * Class:     com_chnic_service_Business
 82  * Method:    analyzeOrder
 83  * Signature: (Lcom/chnic/bean/Order;)V
 84  * java中的静态方法,在C++中的实现,传递的参数是java对象,无返回值
 85  */  
 86 JNIEXPORT void JNICALL Java_com_chnic_service_Business_analyzeOrder (JNIEnv* env,   
 87                                                                      jclass cls,   
 88                                                                      jobject obj)  
 89 {  
 90     jclass order_class = env->GetObjectClass(obj);  
 91     jmethodID getName_method = env->GetMethodID(order_class, "getName", "()Ljava/lang/String;");  
 92     jstring name_str = static_cast<jstring>(env->CallObjectMethod(obj, getName_method));  
 93     const char* pname = env->GetStringUTFChars(name_str, NULL);  
 94   
 95     cout << "Name in Java_com_chnic_service_Business_analyzeOrder: " << pname << endl;  
 96 
 97 
 98     jmethodID notification_method_static = env->GetStaticMethodID(cls, "notificationByStatic", "()V");  
 99     env->CallStaticVoidMethod(cls, notification_method_static);  
100   
101 }  
102 
103 /*
104  * 根据类,构造对应的对象返回
105  */
106 jobject getInstance(JNIEnv* env, jclass obj_class)  
107 {  
108     jmethodID construction_id = env->GetMethodID(obj_class, "<init>", "()V");  
109     jobject obj = env->NewObject(obj_class, construction_id);  
110     return obj;  
111 }  
112 
113 /*
114  * Class:     com_chnic_service_Business
115  * Method:    showArray
116  * Signature: ([I)V
117  * 传递字符串数组,在C++中使用
118  */
119 JNIEXPORT void JNICALL Java_com_chnic_service_Business_showArray
120 (JNIEnv* env, jobject job, jintArray jia)
121 {
122     jint* nums;
123     nums = env->GetIntArrayElements(jia,NULL); 
124 
125     jint length = env->GetArrayLength(jia);
126     cout<<"length:"<<length<<endl;
127     int i;
128     for(i=0;i<length;i++)
129     {
130         cout<<nums[i]<<endl;
131     }
132 }
133 
134 /*
135  * Class:     com_chnic_service_Business
136  * Method:    getIntArray
137  * Signature: ()[I
138  * 返回整形数组
139  */
140 JNIEXPORT jintArray JNICALL Java_com_chnic_service_Business_getIntArray
141   (JNIEnv *env, jobject job)
142 {
143     jsize col=10;
144     jint temp[10]={1,2,3,4,5,6,7,8,9,10};
145     
146     jintArray iarr = env->NewIntArray(col);
147     env->SetIntArrayRegion(iarr, 0, col, temp);
148     return iarr;
149 }
150 
151 /*
152  * Class:     com_chnic_service_Business
153  * Method:    getStringArray
154  * Signature: ([Ljava/lang/String;)[Ljava/lang/String;
155  * 传递一个字符串数组,并且重新构造一个字符串数组,并返回
156  */
157 JNIEXPORT jobjectArray JNICALL Java_com_chnic_service_Business_getStringArray
158 (JNIEnv* env, jobject job, jobjectArray joa)
159 {
160     //打印传递进来的字符串数组
161     jsize si = env->GetArrayLength(joa);
162     //cout<<si<<endl;
163     int i;
164     for(i=0;i<si;i++)
165     {
166         jstring str = (jstring)(env)->GetObjectArrayElement(joa, i);
167         //cout<<str<<endl;
168         const char* pname = env->GetStringUTFChars(str, NULL);  
169         cout<<pname<<endl;
170     }
171     //构造新的字符串数组
172     jstring s1=env->NewStringUTF("123");
173     jstring s2=env->NewStringUTF("456");
174     jstring s3=env->NewStringUTF("789");
175     jstring ss[3]={s1,s2,s3};
176     
177 
178 jobjectArray swArray = env->NewObjectArray(3,env->FindClass("java/lang/String"), env->NewStringUTF(""));
179 //SetObjectArrayElement刷新数组元素内容  
180   for(i = 0; i < 3; i++)
181    env->SetObjectArrayElement(swArray, i, ss[i]) ;
182     return swArray;
183 }
184 
185 /**
186  * java传递二维字符串
187  *
188  */
189 JNIEXPORT void JNICALL Java_com_chnic_service_Business_test2DStringArray
190   (JNIEnv *env, jobject obj, jobjectArray array)
191 {
192  int size = env->GetArrayLength(array);
193  for (int i = 0; i < size; i++) {
194   jobjectArray myarray =(jobjectArray) (env->GetObjectArrayElement(array, i));
195   int length = env->GetArrayLength(myarray);
196   cout<<"length:   "<<length<<endl;
197   for (int j = 0; j < length; j++) {
198    jstring string = (jstring)(env->GetObjectArrayElement(myarray, j));
199    const char * chars =  env->GetStringUTFChars(string, 0);
200    cout<<chars<<"  ";
201     env->ReleaseStringUTFChars(string, chars);
202   }
203   cout<<endl;
204  }
205 }
View Code

 

生成动态链接库后,运行java的main方法,控制台打印信息如下:

Before release: Apple
After release: V
price:1.2
-------------------------
Before release: Pear
After release: X
price:2.1
-------------------------
name is Apple,price is 0.0,amount is 23.
-------------------------
Got a notification.
amount: 30
name is Fruit,price is 0.0,amount is 30.
-------------------------
Name in Java_com_chnic_service_Business_analyzeOrder: orange
Got a notification in a static method.
-------------------------
length:4
1
2
3
4
-------------------------
1
2
3
4
5
6
7
8
9
10
-------------------------
aa
bb
cc
dd
-------------------------
aa
bb
cc
dd
123
456
789
-------------------------
length: 3
一行1号 一行二号 一行三号
length: 3
二行一号 二行二号 二行三号
-------------------------

 

 

 

备注:1、使用Win7+eclipse+VC++6.0开发

   2、VC++创建Win32 Dynamic-Link Library工程

   3、在java调用native方法传递中文字符串时,若java工程或java文件格式不是UTF格式,会有乱码。

posted on 2015-01-09 13:56  过省  阅读(161)  评论(0编辑  收藏  举报

导航