码迷,mamicode.com
首页 > 编程语言 > 详细

java JNI 的实现(2)-java和C/C++的相互调用.

时间:2014-12-02 06:42:27      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   io   ar   color   os   sp   

目录

  概述

  一,java代码

  二,稍微注意通过javah生成的‘C/C++‘.h头文件和源java代码的关系

  三,在C/C++中实现java的native方法(完整C/C++)

    1,修改age,即Java_juk_demo_JSay_changeAge方法

    2,调用java中的‘javaStatic‘方法,和上面C/C+实现方法相似

    3,最后测试

概述

  从第一篇java JNI 的实现(1)-又进一步加深对JVM实现的理解对JNI有了大致的理解之后,并知道JNI中java如何调用C/C++等,这篇文章我们进一步将JNI中,java和C/C++的相互调用.

一,java代码:

  我们稍微对类做了更改,如下:

bubuko.com,布布扣
 1 package juk.demo;
 2 
 3 public class JSay {
 4     //member/class field.
 5     public static String country = "cn";
 6     
 7     public int age = 20;
 8     
 9     //native method.
10     public native void changeAge();
11     
12     public static native void staticSay();
13     
14     //member method.
15     public void getVoid() {
16         
17     }
18     
19     public String getString() {
20         return "json";
21     }
22 
23     public int getInt() {
24         return 1;
25     }
26     
27     private void getUnknown() {
28         
29     }
30     
31     public int[] getIntArray() {
32         return new int[]{1,2};
33     }
34     
35     //static method.
36     public static void javaStatic() {
37          System.out.println(country + ", center china");;
38     }
39     
40     static {
41         System.loadLibrary("JNITestCCPP");
42     }
43         
44 
45     public static void main(String[] args) {
46         //invoke native method.
47         JSay.staticSay();
48         
49         JSay jSay = new JSay();
50         System.out.println("before invoke native,age=" + jSay.age);
51         jSay.changeAge();
52         System.out.println("after invoke native,age=" + jSay.age);
53         
54     }
55 
56 }
View Code

  这次,java代码有两个native方法(changeAge和staticSay),并且有许多成员和类的普通java方法(主要是研究通过javah产生的.h头文件和源java代码直接的关系),

  我们这次的目的,一是在java中调用‘changeAge‘ native方法的时候,在C/C++代码中对其对象的age属性进行更改(当然,一般成员变量都是封装的,这里只是为了测试);二是在java调用‘staticSay‘ native方法的时候,在C/C++代码中,反过来调用java的‘javaStatic‘方法.

二,稍微注意通过javah生成的‘C/C++‘.h头文件和源java代码的关系:

bubuko.com,布布扣
 1 /* DO NOT EDIT THIS FILE - it is machine generated */
 2 #include "jni.h"
 3 /* Header for class juk_demo_JSay */
 4 
 5 #ifndef _Included_juk_demo_JSay
 6 #define _Included_juk_demo_JSay
 7 #ifdef __cplusplus
 8 extern "C" {
 9 #endif
10 /*
11  * Class:     juk_demo_JSay
12  * Method:    changeAge
13  * Signature: ()V
14  */
15 JNIEXPORT void JNICALL Java_juk_demo_JSay_changeAge
16   (JNIEnv *, jobject);
17 
18 /*
19  * Class:     juk_demo_JSay
20  * Method:    staticSay
21  * Signature: ()V
22  */
23 JNIEXPORT void JNICALL Java_juk_demo_JSay_staticSay
24   (JNIEnv *, jclass);
25 
26 #ifdef __cplusplus
27 }
28 #endif
29 #endif
View Code

  我们发现,通过javah命令生成的C/C++.h头文件,不会在.h头文件中出现(这其实也是很合情理的,但是我们却可以通过java中的native方法对应的.h中的方法的参数‘JNIEnv *‘去获得java中所有的成员).

  三,在C/C++中实现java的native方法(完整C/C++):

bubuko.com,布布扣
 1 #include <iostream>
 2 #include "juk_demo_JSay.h"
 3 using namespace std;
 4 
 5 //3 ways to get jclass:
 6 /*
 7 1,(JNIEnv *)->FindClass(class-name),which find the class by the classpath.
 8 2,(JNIEnv *)->GetObjectClass(jobject).
 9 3,(JNIEnv *)->GetSuperclass(jobject).
10 */
11 
12 /*
13  * Class:     juk_demo_JSay
14  * Method:    changeAge
15  * Signature: ()V
16  */
17 JNIEXPORT void JNICALL Java_juk_demo_JSay_changeAge
18   (JNIEnv *env, jobject obj) {
19     jclass JSayClass = env->GetObjectClass(obj);
20     jfieldID ageId = env->GetFieldID(JSayClass, "age", "I");
21     //env->GetIntField(obj, ageId);
22     env->SetIntField(obj, ageId, 22);    //set the age with a new value.
23 }
24 
25 /*
26  * Class:     juk_demo_JSay
27  * Method:    staticSay
28  * Signature: ()V
29  */
30 JNIEXPORT void JNICALL Java_juk_demo_JSay_staticSay
31   (JNIEnv *env, jclass clz) {
32     //jclass JSayClass = env->FindClass("juk.demo.JSay");
33 
34     //javaStatic method.
35     //the third argument,can be fetch with ‘javap‘ command.
36     jmethodID getStaticMethodId = env->GetStaticMethodID(clz, "javaStatic", "()V");
37     env->CallStaticVoidMethod(clz, getStaticMethodId, NULL);
38 
39     //get age field.
40     /*jfieldID countryId = env->GetStaticFieldID(JSayClass, "country", "Ljava/lang/String;");
41     env->GetStaticObjectField(JSayClass, countryId);*/
42 }
View Code

    1,修改age,即Java_juk_demo_JSay_changeAge方法,我们首先要获得jclass对象(jclass对应于java中的Class对象),而jclass对象的获得可以根据3中方式:

1,(JNIEnv *)->FindClass(class-name),which find the class by the classpath.
2,(JNIEnv *)->GetObjectClass(jobject).
3,(JNIEnv *)->GetSuperclass(jobject).

然后可以通过(JNIEnv *)获得属性的ID,并修改.稍微注意的是‘env->GetFieldID‘方法中的第3个参数,是为了区别方法的重载问题,

如下表(来自oracle的Chapter 3: JNI Types and Data Structures)

Java VM Type Signatures
Type SignatureJava Type
Z boolean
B byte
C char
S short
I int
J long
F float
D double
L fully-qualified-class ; fully-qualified-class
[ type type[]
( arg-types ) ret-type method type

sun为了方便我们程序员,写一个工具(即,jdk中的javap),而不用我们记忆那些类型签名,例如,我们可以在包含该java的class的目录上(通过命令行),输入 ‘javap -s -public juk.demo.JSay‘,即可得到对应的签名,如:

bubuko.com,布布扣
 1 Compiled from "JSay.java"
 2 public class juk.demo.JSay extends java.lang.Object{
 3 public static java.lang.String country;
 4   Signature: Ljava/lang/String;
 5 public int age;
 6   Signature: I
 7 public juk.demo.JSay();
 8   Signature: ()V
 9 public native void changeAge();
10   Signature: ()V
11 public static native void staticSay();
12   Signature: ()V
13 public void getVoid();
14   Signature: ()V
15 public java.lang.String getString();
16   Signature: ()Ljava/lang/String;
17 public int getInt();
18   Signature: ()I
19 public int[] getIntArray();
20   Signature: ()[I
21 public static void javaStatic();
22   Signature: ()V
23 public static void main(java.lang.String[]);
24   Signature: ([Ljava/lang/String;)V
25 }
View Code

    2,调用java中的‘javaStatic‘方法,和上面C/C+实现方法相似,不过由于在java源码中,native被定义成了类方法,所以不用获得jclass,而直接从参数获取.同理,通过(JNIEnv *)获得java中的javaStatic方法,并调用.

    最后,我们再java主函数中进行测试,结果为:

cn, center china
before invoke native,age=20
after invoke native,age=22

 

java JNI 的实现(2)-java和C/C++的相互调用.

标签:des   style   blog   http   io   ar   color   os   sp   

原文地址:http://www.cnblogs.com/listened/p/4136420.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!