其他分享
首页 > 其他分享> > JNI接口native函数调用过程

JNI接口native函数调用过程

作者:互联网

void dvmCallMethodV(Thread* self, const Method* method, Object* obj,
    bool fromJni, JValue* pResult, va_list args)
{
    ...
    //判断函数是否为Native函数
    if (dvmIsNativeMethod(method)) {
          TRACE_METHOD_ENTER(self, method);
        
         //调用nativeFunc
        (*method->nativeFunc)((u4*)self->interpSave.curFrame, pResult,
                              method, self);
        TRACE_METHOD_EXIT(self, method);
    } else {
        //如果是java函数,调用解释器去解释执行对应的dex方法字节码
        dvmInterpret(self, method, pResult);
    }
   ...
}

dvmCallMethodV函数会先判断是否为Method是否为native函数,如果是就调用Method->nativeFunc对应的地址。如果是java层函数,调用解释器去解释执行对应的dex方法字节码。

DalvikBridgeFunc nativeFunc;

typedef void (*DalvikBridgeFunc)(const u4* args, JValue* pResult,
    const Method* method, struct Thread* self);

我们看一下他的定义,这个一个函数指针。那他的值是多少呢?
在loadMethodFromDex中会对其进行赋值,在从dex中加载类的时候会调用loadMethodFromDex。也就是当类需要使用第一次被加载时会调用loadMethodFromDex,然后会解析类中的每一个方法并为其构建Method结构,同时函数会判断此方法是否为native类型的,如果是就会将Method结构的nativeFunc字段设置为dvmResolveNativeMethod函数地址。

if (dvmIsNativeMethod(meth)) {
     meth->nativeFunc = dvmResolveNativeMethod;
     meth->jniArgInfo = computeJniArgInfo(&meth->prototype);
}

dvmResolveNativeMethod函数首先调用dvmLookupInternalNativeMethod判断是否为虚拟机实现的native函数,如果是直接调用。如果是其他so库实现的native函数则会调用lookupSharedLibMethod从对应的so库导出函数中查找指定的函数名称然后调用。

void dvmResolveNativeMethod(const u4* args, JValue* pResult,
    const Method* method, Thread* self)
{
    ClassObject* clazz = method->clazz;

    
    DalvikNativeFunc infunc = dvmLookupInternalNativeMethod(method);
    if (infunc != NULL) {
        /* resolution always gets the same answer, so no race here */
        IF_LOGVV() {
            char* desc = dexProtoCopyMethodDescriptor(&method->prototype);
            LOGVV("+++ resolved native %s.%s %s, invoking",
                clazz->descriptor, method->name, desc);
            free(desc);
        }
        if (dvmIsSynchronizedMethod(method)) {
            ALOGE("ERROR: internal-native can't be declared 'synchronized'");
            ALOGE("Failing on %s.%s", method->clazz->descriptor, method->name);
            dvmAbort();     // harsh, but this is VM-internal problem
        }
        DalvikBridgeFunc dfunc = (DalvikBridgeFunc) infunc;
        dvmSetNativeFunc((Method*) method, dfunc, NULL);
        dfunc(args, pResult, method, self);
        return;
    }



    /* now scan any DLLs we have loaded for JNI signatures */
    void* func = lookupSharedLibMethod(method);
   
}

标签:nativeFunc,调用,函数,self,函数调用,Method,JNI,method,native
来源: https://www.cnblogs.com/revercc/p/16194323.html