欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

传智播客第三讲,智播客第三讲

来源: javaer 分享于  点击 21341 次 点评:152

传智播客第三讲,智播客第三讲



第三讲 本课程讲解在被调用的C/C++函数中如何取得/设定Java属性值、如何调用Java类的方法和调用Java类的父类的方法,并编写应用实例

一、取得Java属性,设定Java属性值 取得了相应属性的jfieldID之后,就可以用Set<TYPE>Field, Get<TYPE>Field, SetStatic<TYPE>Field跟GetStatic<TYPE>Field等函数来对Java属性进行操作了。
Set/GetBooleanField
Set/GetByteField
Set/GetDoubleField
Set/GetFloatField
Set/GetIntField
Set/GetLongField
Set/GetShortField
Set/GetObjectField

Set/GetStaticBooleanField
Set/GetStaticByteField
Set/GetStaticDoubleField
Set/GetStaticFloatField
Set/GetStaticIntField
Set/GetStaticLongField
Set/GetStaticShortField
Set/GetStaticObjectField


二、怎么样获取数组属性呢?
可以使用GetObjectField来取得数组类型的属性。

示例: public class Hello {

    public int number = 10;        public native void test () ;         public static void main( String [] args ) {                Hello hello = new Hello ();               hello . test() ;                System .out . println( hello .number ) ;         }    }
  JNIEXPORT void JNICALL Java_Hello_test ( JNIEnv * env , jobject obj){       jclass hello_clazz = env- >GetObjectClass ( obj) ;    jfieldID id_number = env- >GetFieldID ( hello_clazz, "number", "I") ;    jint number = env- >GetIntField ( obj, id_number );       cout << number << endl;       env -> SetIntField( obj, id_number , 100L ) ;    }
 
三、Java方法的调用
1)JNIEnv提供了众多的Call<TYPE>Method跟CallStatic<TYPE>Method,还有CallNonvirtual<TYPE>Method函数,需要通过GetMethodID取得相应方法的jmethodID来传入到上述函数的参数中。

2)调用实例方法的三种形式
Call<TYPE>Method(jobject obj, jmethodID id, ...);
Call<TYPE>MethodV(jobject obj, jmethodID id, va_list lst);
Call<TYPE>MethodA(jobject obj, jmethodID id, jvalue* v);

第一种是最常用的方式。
第二种是当调用这个函数的时候有一个指向参数表的va_list变量时使用的。
第三种是当调用这个函数的时候有一个指向jvalue或jvalue数组的指针时用的。


第一种:
env->CallBooleanMethod(obj, id_function, 100L, 3.44, L'3');
第三种:
boolean function(int i, double d, char c){
...
}

jvalue * args = new jvalue[3];
args[0].i = 100L;
args[1].d = 3.44;
args[2].c = L'3';

env->CallBooleanMethodA(obj, id_function, args);
delete [] args;

3)调用静态方法的三种形式
CallStatic<TYPE>Method(jclass clazz, jmethodID id, ...);
CallStatic<TYPE>MethodV(jobject obj, jmethodID id, va_list lst);
CallStatic<TYPE>MethodA(jobject obj, jmethodID id, jvalue* vars);

  

三、CallNonvirtual<TYPE>Method
1)思考一下吧
有如下C++代码:
class Father 
{

     public:
          virtual void function()
          {
               cout << "father:func" << endl;
          }
};

class child:public Father
{
     public:
          void function()
          {
               cout << "child:func" << endl;
          }
};

想想这段代码调用的是哪个类的成员函数?父类函数去掉virtual和不去掉有区别的哦。
Father* p = new Child();
p->function();

2)在JNI中定义的CallNonvirtual<TYPE>Method就能够实现子类对象调用父类方法的功能。如果想要调用一个对象的父类的方法,而不是子类的这个方法的话,就可以使用CallNonvirtual<TYPE>Method。


3)要使用它,首先要取得父类及要调用的父类方法的jmethodID,然后传入到这个函数就能通过子类对象呼叫被复写(override)的父类的方法了。
4)测试代码:
public class Father {                public void function(){             System .out . println( "father:function" );        }
public class child extends Father {                public void function(){             System .out . println( "child:function" );        }
}   
public class Hello {
    Father p = new child ();        public native void test () ;         public static void main( String [] args ) {                Hello hello = new Hello ();               hello . test() ;     }    }
  JNIEXPORT void JNICALL Java_Hello_test ( JNIEnv * env , jobject obj){       jclass hello_clazz = env- >GetObjectClass ( obj) ;    jfieldID id_p = env- >GetFieldID ( hello_clazz, "p", "Lcom/example/jnitest1/Father;" ) ;    jobject p = env- >GetObjectField ( obj, id_p );        jclass clazz_Father = env- >FindClass ( "com/example/jnitest1") ;    jmethodID id_Father_function = env- >GetMethodID ( clazz_Father, "function", "()V" );    //  env->CallVoidMethod(p, id_Father_function);    env -> CallNonvirtualVoidMethod( p , clazz_Father , id_Father_function) ;    }
   

相关文章

    暂无相关文章
相关栏目:

用户点评