java jni框架,Java JNI 简明教程(一)——传智播客JNI笔记(王泽佑)

package cn.itcast;

public calss TestNative {

public native void sayHello();

public static void main(String[] arg){

}

}```

2. 用javah.exe生成包含native方法的C/C++头文件

javah -jni(默认)

javah cn.itcast.TestNative //由类名执行生成C/C++头文件

生成的头文件内容:JNIEXPORT void JNICALL Java_cn_itcast_TestNative_SayHello (JNIEnv*, jobject)

3. 参照生成的头文件生成C/C++源文件

在VS下:Win32工程-->DLL-->空的工程-->结束

把生成的头文件引入到C++工程中,从JDK/include和include/win32中

jni.h和jni_md.h文件,然后创建一个新的C++源文件

```java

#include

#include "cn_itcast_TestNative.h"

JNIEXPORT void JNICALL Java_cn_itcast_TestNative_sayHello

(JNIEnv* env, jobject obj){

count<

4. 返回Java写Java调用dll代码部分

在主函数中:

System.loadLibrary("nativeCode")//写入你生成的dll文件名,但不要写“.dll”java会自动识别Windows还是Linux系统

new TestNative().sayHello();

运行一下,结果:

Hello world

----

##使用JNI的两个弊端

1. 使用JNI,这个Java Application就不跨平台了,如果要移植到其他平台那么native代码就要重新编写,编译。

2. Java是强类型语言,C/C++不是,因此使用JNI要格外小心

**总之,尽量少用JNI**

本地代码访问Java代码

* 在本地调用的C/C++函数中也可以反过来访问Java程序中的类

* javah工具生成C/C++函数生命中,可以看到两个参数

> JNI* env 实际上代表了Java环境,通过JNIEnv*指针,就可以对Java端代码进行操作,例如:创建Java类的对象,调用Java对象的方法,获取Java对象属性等

* JNIEnv类中有很多函数可以用。

NewObject/NewString/New Array

Get/SetField

CallMethod /CallStaticMethod 等许多函数某个类型的变量

> jobject* obj 被定义为_jobject

* Java操作对象为引入操作,而C/C++中使用指针对对象操作

* jobject* obj 指向一个Java对象的引用,这个对象引用是Java中Native方法所对应的对象

<1>若native方法非静态,它指向native方法所对应的实例

<2>若native方法静态(static)那么它指向native所对应的class对象:Class.class

### Java类型在C/C++中的映射关系

| Java | 本地类型 | JNI定义的别名(jni.h中定义) |

| ------- |:------------------:| -------:|

| int | long | jint/jsize |

| long | _int64 | jlong |

| byte | signed char | jbyte |

| boolean | unsigned char | jboolen |

| char | signed short | jchar |

| short | short | jshort |

| float | float | jfloat |

| double | double | jdouble |

| Object | _jobject* | jobject |

### jclass的取得

typedef _jclass* jclass

为了使C/C++使用Java类,Jni.h头文件中专门定义了jclass类型表示Java中的class类

JNIEnv类中有如下几个简单的函数可以取得jclass:

- jclass FindClass(const char * clsName);

- jclass GetObjectClass (jobject obj);

- jclass GetSuperClass (jclass obj);

Findclass会在classpath系统环境变量下寻找类

传入完整的类名,注意包与包之间是'/'而不是'.'来分隔

如:jclass cls_string=env->FindClass("Java/lang/String")

C/C++访问Java端代码,一个常用的应用就是获取类的属性和调用类的方法,为了在C/C++中表示属性和方法JNI在jni.h头文件中定义了jfieldID,jmethodID分别代表Java端属性和方法

我们在访问或设置Java属性时,必须先取得代表Java属性的jfieldID,然后才可以在本地代码进行Java属性操作;同样,需要使用Java端方法时,也是要取得代表该方法的jmethodID才能对Java方法调用。

使用JNIEnv的GetFieldID/GetMethodID GetStaticFieldID/GetStaticMethodID 来取得相应的jfieldID和jmethodID

* 方法原型:GetFieldID/GetStaticFieldID/GetMethodID/GetStaticMethodID(jclass clazz,const char* name,const char* sign)

如:env->GetMethodID(data_clazz,"","()V")

* Sign签名,用来表示取得的属性/方法的类型

| 类型 | 相应签名 |

| ------- |:------------------:|

| boolean | Z |

| byte | B |

| char | C |

| short | S |

| int | I |

| long | L |

| float | F |

| double | D |

| void | V |

| object | L 用“/”分隔包的完整类名;如:Ljava/lang/String; |

| Array(数组) | [Sign 如[L [Ljava/lang/object; |

| Method | (Type)V 若指定“(I)V” 则取回 void function(int)的jmethodID
若指定“(D)V”则取回void function(double)的jmethodID|

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值