240 发简信
IP属地:四川
  • 120
    Android JNI学习(二)——实战JNI之“hello world”

    本系列文章如下: Android JNI(一)——NDK与JNI基础Android JNI学习(二)——实战JNI之“hello world”Android JNI学习(三)...

  • native函数没有指针数组哦,我看了一下android Q里边的实现,在注册native函数的时候,通过反射获取到java方法地址后,直接将native 函数的地址,写入到 对应java 方法地址开始往后的4个字节或8个字节的内存空间里边。
    具体实现在: android/art/runtime/art_method.h
    template<typename T>
    ALWAYS_INLINE void SetNativePointer(MemberOffset offset, T new_value, PointerSize pointer_size) {
    static_assert(std::is_pointer<T>::value, "T must be a pointer type");
    const auto addr = reinterpret_cast<uintptr_t>(this) + offset.Uint32Value();
    ///这边将native函数地址进行写入哦
    if (pointer_size == PointerSize::k32) {
    uintptr_t ptr = reinterpret_cast<uintptr_t>(new_value);
    *reinterpret_cast<uint32_t*>(addr) = dchecked_integral_cast<uint32_t>(ptr);
    } else {
    *reinterpret_cast<uint64_t*>(addr) = reinterpret_cast<uintptr_t>(new_value);
    }
    }

    大致调用栈为:
    SetNativePointer()
    SetDataPtrSize()
    SetEntryPointFromJniPtrSize()
    SetEntryPointFromJni()
    RegisterNative()
    RegisterNatives()
    jniRegisterNativeMethods()
    registerNativeMethods()
    RegisterMethodsOrDie()