Java JNI学习(二)

来源:互联网 发布:字幕自动生成软件 编辑:程序博客网 时间:2024/06/05 07:24

今天继续记录JNI学习过程,今日内容为本地代码调用Java代码。

在刚开始的那篇中,我们在c++代码中输出了一句Hello JNI来开启JNI学习之旅,顺便从中也知道了在Java中用native方法可以调用C++中的代码。
其实今天所看到的也可以反过来用,在本地代码(也就是C++代码)中同样可以调用Java中的代码。
延续上一篇记录的笔记,我们通过javah工具生成的c++头文件中,会发现如下的函数声明:

JNIEXPORT void JNICALL Java_com_wang_TestNative_sayHello(JNIEnv* ,jobject)

这个声明中有两个参数需要传递,而这两个参数就和Java代码有关。具体来看c++源文件中的代码:

JNIEXPORT void JNICALL Java_com_wang_TestNative_sayHello(JNIEnv* env ,jobject obj){      //.........}

JNIEnv指针类型的参数实际上代表了Java环境。通过这个JNIEnv*指针,就可以对Java端的代码进行操作,如创建Java类的对象,调用Java的方法,获取Java对象的属性等等,有很大的作用。JNIEnv*有很多函数可以用,像:

NewObject/NewString/New<TYPE>Array;             //创建Java的对象用

Get/Set<TYPE>Field;                                               //获取或设置某一个对象的属性

Get/SetStatic<TYPE>Field;

Call<TYPE>Method/CallStatic<TYPE>Method等等很多函数。


jobject是一个指向java对象的引用,这个本地方法是非静态方法,因此这里代表了用了这个本地方法的java实例。


接下来看看jclass的取得:为了能够在C/C++中使用Java类。JNI.h头文件定义了jclass类型来表示Java中的Class类,可以通过下面函数取得:

jclass FindClass(const char* clsName);jclass GetObjectClass(jobject obj);jclass GetSuperClass(jclass obj);
另外在c++代码中访问Java端的代码,常见的就是获得类的属性和调用类方法,因此在头文件中会发现jfieldID和jmethodID两个来代表java端的属性和方法。

要访问java属性时要先取得Java属性的jfieldID,然后才能在本地代码访问java属性,同样的要先取得Java属性的jmethodID才能进行Java方法调用。

这下面首先来介绍获取属性的用法。。。

先在java代码中写一个属性:

public int number = 10;

因为是接着上次的那个工程,本有一个sayHello()方法,因此就在对于的c++中的Java_com_wang_TestNative_sayHello方法中来调用java中德number那个属性。

接下来就是在c++代码中书写了:

JNIEXPORT void JNICALL Java_com_wang_TestNative_sayHello(JNIEnv *env, jobject obj){//cout<<"Hello JNI!"<<endl;jclass class_TestNative = env->GetObjectClass(obj);jfieldID id_number = env->GetFieldID(class_TestNative,"number","I");jint number = env->GetIntField(obj,id_number);cout<<number<<endl;env->SetIntField(obj,id_number,100L);}

其中GetObjectClass(obj)就是获得TestNative类了,获得类后,就可以通过jfieldID获得number属性的id,GetFieldID中的“number”对应java中要获得的那个属性的名字,“I”对应的是属性的类型int。。然后再用GetIntField获得number属性的值。

SetIntField当然就是设置java中number属性值的方法了,这里将它设置为100.因为java中的int类型对应c++中的长整型类型,所以要写100L。

然后编译通过。

最后在java中的main函数里写上如下代码测试一下:

public static void main(String[] args) {// TODO Auto-generated method stubTestNative test = new TestNative();test.sayHello();System.out.println(test.number);}

这样就会发现最后的输出结果,第一个是10,第二个是100.

也就是第一个是用c++代码输出,证明取得了Java中的number属性,第二个是用java代码输出,是100,说明通过c++代码改变了number的值。



0 0
原创粉丝点击