Jni访问java的属性,方法

基本属于翻译。

 

首先必须存在之前传入的jobject obj,在根据 JNIEnv来获取jclass。

jclass cls = (*env)->GetObjectClass(env, obj);
当获取的jclass之后,也就知道该class的排布,之后开始获取相关的field。
  jfieldID fid = (*env)->GetFieldID(env, cls, "s", "Ljava/lang/String;");
之后就是对于field的解析工作,这里这个是string,由于需要返回的是具体instance中的树枝,所以这里需要obj。
jstring jstr = (*env)->GetObjectField(env, obj, fid);

如果是int等primitive参数,使用GetIntField系列的就好。

 

jni区域标识符

 

这个标识符用来描述区域的表示,已L开始,[代表数组, [I是int类型的数组,并且已分号结尾。

如果是类的应用,例如java.lang.String

书写为"Ljava/lang/String;"

 

具体的表格如下

 

Field Descriptor
Java Language Type
Z
boolean
B
byte
C
char
S
short
I
int
J
long
F
float
D
double

 

Field Descriptor
Java Language Type
"Ljava/lang/String;"
String
"[I"
int[]
"[Ljava/lang/Object;"

Object[]

 

可以利用工具javap来检查

 

javap -s -p YouClass

s Ljava/lang/String;
这里的函数的描述符。顺序是(param)returntype,其中参数和参数之间无需加任何符号。
 
 
Method Descriptor
Java Language Type
"()Ljava/lang/String;"
String f();
"(ILjava/lang/Class;)J"
long f(int i, Class c);
"([B)V"
String(byte[] bytes);
javap效果,如下
javap -s -p InstanceMethodCall

private callback ()V
public static main ([Ljava/lang/String;)V
private native nativeMethod ()V
实例代码,如果在C中启动Runnable的run函数
jobject thd = ...; /* a java.lang.Thread instance */
jmethodID mid;
jclass runnableIntf = 
    (*env)->FindClass(env, "java/lang/Runnable");          /*或者这里可以使用GetObjectClass来获取jclass*/
if (runnableIntf == NULL) {
    ... /* error handling */
}
mid = (*env)->GetMethodID(env, runnableIntf, "run", "()V");
if (mid == NULL) {
    ... /* error handling */
}
(*env)->CallVoidMethod(env, thd, mid);
... /* check for possible exceptions */
 
C中回调java的函数
Call<type>Method----其中type代表该函数的返回值
 
每次都这作样的查找必然会损伤效率,这里缓存查找的结果
有2中方式,一种是在首次使用的时候,一种是在初始化的时候
1.首次使用很简单。
if(NULL = field_id) field_id = (*env)->GetXXXX
2.在构造中初始化其实是对于1方案的改进,因为1方案无法解决多线程重入判断的语句,而且还多了一条if语句,不符合追求最高性能的方法
class InstanceMethodCall {
    private static native void initIDs();
    private native void nativeMethod();
    private void callback() {
        System.out.println("In Java");
    }
    public static void main(String args[]) {
        InstanceMethodCall c = new InstanceMethodCall();
        c.nativeMethod();
    }
    static {
        System.loadLibrary("InstanceMethodCall");
        initIDs();
    }
}

其中 ,利用构造函数最先被调用的特点来初始化
JNIEXPORT void JNICALL 
Java_InstanceMethodCall_initIDs(JNIEnv *env, jclass cls)
{
    MID_InstanceMethodCall_callback =
        (*env)->GetMethodID(env, cls, "callback", "()V");
}

 JNIEXPORT void JNICALL 
 Java_InstanceMethodCall_nativeMethod(JNIEnv *env, jobject obj)
 {
     printf("In C/n");
     (*env)->CallVoidMethod(env, obj,
                            MID_InstanceMethodCall_callback);
 }
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值