1.Java访问Native的步骤
* 在Java类中声明一个本地native方法。
* 使用Javah命令生成包含native方法定义的C/C++头文件。
* 按照生成的C/C++头文件来写C/C++源文件。
* 将C/C++源文件编译成动态链接库。
* 把DLL文件加入到PATH环境变量下。
* Java类中加载DLL,然后调用声明的native方法。
System.loadLibrary("nativeCode"); //如果找不到的话会抛出运行时异常。
(注:JNI会影响JavaApplication的跨平台特性。
Java是强类型的语言而C/C++不是,所以容易出错。)
2. JNIEnv类型实际上代表了Java环境。通过这个JNIEnv*指针,就可以对Java端的
代码进行操作。例如,创建Java类的对象,调用Java对象的方法,获取Java对象的
属性等等。JNIEnv的指针会被JNI传入到本地方法的实现函数中来对Java端的代码进
行操作。
NewObject/NewString/New<TYPE>Array
Get/Set<TYPE>Field
Get/SetStatic<TYPE>Field
Call<TYPE>Method/CallStatic<TYPE>Method
3.Java类型映射
int long jint/jsize I
long _int64 jlong L
byte signed char jbyte B
boolean unsigned char jboolean Z
char unsigned short jchar C
short short jshort S
float float jfloat F
double double jdouble D
object _jobject* jobject Ljava/lang/String;
Array [Ljava/lang/object;
4.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");)
5.在C/C++本地代码中访问Java端的代码,一个常见的应用就是获取类的属性和调用类的方法。为了在C/C++中表示属性
和方法,JNI在Jni.h头文件中定义了jfieldID,jmethodID
类型来分别代表Java端的属性和方法。
GetFieldID/GetMethodID
GetStaticFieldID/GetStaticMethodID
6.引用Java层代码
* jclass clazz_TestNative = env->FindClass("cn/itcast/TestNative");
jmethodID id_func = env ->GetMethodID(clazz_TestNative,"toString","(I)V");
(注:最后一个参数是根据参数类型区分被重载的函数)
------------------------
* jclass hello_clazz = env->GetObjectClass(obj);
jfieldID fieldID_prop= env->GetFieldID(hello_clazz,"property","I");
jmethodID methodID_func = env->GetMethodID(hello_clazz,"function","(ILjava/util/Date;[I)I");
env->CallIntMethod(obj,methodID_func,OL,NULL,NULL);
------------------------
* jclass clazz_TestNative = env->GetObjectClass(obj);
jfieldID id_number = env_GetFieldID(clazz_TestNative,"number","I");
jint number = env->GetIntField(obj,id_number);
env->SetIntField(obj,id_number,100L);
------------------------
boolean function(int i,double d,char c){...}
* env->CallBooleanMethod(obj,id_function,100L,3.44,L'3');
* jvalue *args = new jvlaue[3];
args[0].i = 100L;
args[1].d = 3.44;
args[3].c = L'3';
7.在JNI中定义的CallNonvirtual<TYPE>Method就能够实现子类对象调用父类方法的功能。
如果想调用一个对象的父类的方法,而不是子类的这个方法的话,就可以使用CallNonvirtual<TYPE>Method。
* 在Java类中声明一个本地native方法。
* 使用Javah命令生成包含native方法定义的C/C++头文件。
* 按照生成的C/C++头文件来写C/C++源文件。
* 将C/C++源文件编译成动态链接库。
* 把DLL文件加入到PATH环境变量下。
* Java类中加载DLL,然后调用声明的native方法。
System.loadLibrary("nativeCode"); //如果找不到的话会抛出运行时异常。
(注:JNI会影响JavaApplication的跨平台特性。
Java是强类型的语言而C/C++不是,所以容易出错。)
2. JNIEnv类型实际上代表了Java环境。通过这个JNIEnv*指针,就可以对Java端的
代码进行操作。例如,创建Java类的对象,调用Java对象的方法,获取Java对象的
属性等等。JNIEnv的指针会被JNI传入到本地方法的实现函数中来对Java端的代码进
行操作。
NewObject/NewString/New<TYPE>Array
Get/Set<TYPE>Field
Get/SetStatic<TYPE>Field
Call<TYPE>Method/CallStatic<TYPE>Method
3.Java类型映射
int long jint/jsize I
long _int64 jlong L
byte signed char jbyte B
boolean unsigned char jboolean Z
char unsigned short jchar C
short short jshort S
float float jfloat F
double double jdouble D
object _jobject* jobject Ljava/lang/String;
Array [Ljava/lang/object;
4.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");)
5.在C/C++本地代码中访问Java端的代码,一个常见的应用就是获取类的属性和调用类的方法。为了在C/C++中表示属性
和方法,JNI在Jni.h头文件中定义了jfieldID,jmethodID
类型来分别代表Java端的属性和方法。
GetFieldID/GetMethodID
GetStaticFieldID/GetStaticMethodID
6.引用Java层代码
* jclass clazz_TestNative = env->FindClass("cn/itcast/TestNative");
jmethodID id_func = env ->GetMethodID(clazz_TestNative,"toString","(I)V");
(注:最后一个参数是根据参数类型区分被重载的函数)
------------------------
* jclass hello_clazz = env->GetObjectClass(obj);
jfieldID fieldID_prop= env->GetFieldID(hello_clazz,"property","I");
jmethodID methodID_func = env->GetMethodID(hello_clazz,"function","(ILjava/util/Date;[I)I");
env->CallIntMethod(obj,methodID_func,OL,NULL,NULL);
------------------------
* jclass clazz_TestNative = env->GetObjectClass(obj);
jfieldID id_number = env_GetFieldID(clazz_TestNative,"number","I");
jint number = env->GetIntField(obj,id_number);
env->SetIntField(obj,id_number,100L);
------------------------
boolean function(int i,double d,char c){...}
* env->CallBooleanMethod(obj,id_function,100L,3.44,L'3');
* jvalue *args = new jvlaue[3];
args[0].i = 100L;
args[1].d = 3.44;
args[3].c = L'3';
7.在JNI中定义的CallNonvirtual<TYPE>Method就能够实现子类对象调用父类方法的功能。
如果想调用一个对象的父类的方法,而不是子类的这个方法的话,就可以使用CallNonvirtual<TYPE>Method。