zoukankan      html  css  js  c++  java
  • 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格式,会有乱码。

  • 相关阅读:
    MyEclipse快捷键大全
    mac下配置android环境变量
    JAVA NIO 简单介绍
    android读取大图片并缓存
    Android  <meta-data>
    iPhone 6/6 Plus国行版开卖当日抢购攻略
    A380上11万一张的机票什么享受?来看看
    连载15年!《火影忍者》终于迎来大结局
    Windows 技术预览版
    纪录片《天安门》
  • 原文地址:https://www.cnblogs.com/gaojiang/p/4213155.html
Copyright © 2011-2022 走看看