JNI接口native函数调用过程
作者:互联网
- dvmCallMethodV函数来执行方法,
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方法字节码。
- method->nativeFunc对应的地址
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