• 在Android源码中查找Java代码中native函数对应的C++实现


    在Android源码中查找Java代码中native函数对应的C++实现

    背景

    原文:https://www.cnblogs.com/coding-way/p/4172339.html

    Android源码中很多关键代码都是C++实现的,java通过jni来调用,经常会看到java中这样的代码:

        static native Thread currentThread();
    

    方法

    如何根据方法名找到其对应的C++实现,有两个方法。

    先来个java代码的示例VMThread.java:

    package java.lang;
    
    class VMThread {
        Thread thread;
        int vmData;
    
        VMThread(Thread t) {
            thread = t;
        }
    
        native static void create(Thread t, long stackSize);
    
        static native Thread currentThread();
        static native boolean interrupted();
        static native void sleep (long msec, int nsec) throws InterruptedException;
        static native void yield();
    
        native void interrupt();
    
        native boolean isInterrupted();
        ......
    }
    

    我们要查找currentThread方法的实现。

    方法一

    由于Android源码中对每个native实现都会写一个java方法名和C++方法名映射的列表,所以我们直接搜索这个列表内容即可。

     $ grep -rns '"currentThread"' ./*
    ./art/compiler/dex/quick/dex_file_method_inliner.cc:108:    "currentThread",         // kNameCacheCurrentThread
    匹配到二进制文件 ./dalvik/vm/native/.java_lang_VMThread.cpp.swp
    ./dalvik/vm/native/java_lang_VMThread.cpp:241:    { "currentThread",  "()Ljava/lang/Thread;",
    ./external/android-mock/tests/com/google/android/testing/mocking/AndroidMockGeneratorTest.java:249:    Method method = Thread.class.getMethod("currentThread");
    ./external/android-mock/tests/com/google/android/testing/mocking/AndroidMockGeneratorTest.java:407:    Method method = Thread.class.getMethod("currentThread");
    

    可以看到,在文件./dalvik/vm/native/java_lang_VMThread.cpp中找到currentThread方法相关的信息,后面()Ljava/lang/Thread代表这个方法的返回值。

    进入java_lang_VMThread.cpp这个文件可以看到:

     17 /*
     18  * java.lang.VMThread
     19  */
     20 #include "Dalvik.h"
     21 #include "native/InternalNativePriv.h"
     22 
     23 
     24 /*
     25  * static void create(Thread t, long stacksize)
     26  *
     27  * This is eventually called as a result of Thread.start().
     28  *
     29  * Throws an exception on failure.
     30  */
     31 static void Dalvik_java_lang_VMThread_create(const u4* args, JValue* pResult)
     32 {
     33     Object* threadObj = (Object*) args[0];
     34     s8 stackSize = GET_ARG_LONG(args, 1);
     35 
     36     /* copying collector will pin threadObj for us since it was an argument */
     37     dvmCreateInterpThread(threadObj, (int) stackSize);
     38     RETURN_VOID();
     39 }
     40 
     41 /*
     42  * static Thread currentThread()
     43  */
     44 static void Dalvik_java_lang_VMThread_currentThread(const u4* args,
     45     JValue* pResult)
     46 {
     47     UNUSED_PARAMETER(args);
     48 
     49     RETURN_PTR(dvmThreadSelf()->threadObj);
     50 }
     51 
    ......
    237 
    238 const DalvikNativeMethod dvm_java_lang_VMThread[] = {
    239     { "create",         "(Ljava/lang/Thread;J)V",
    240         Dalvik_java_lang_VMThread_create },
    241     { "currentThread",  "()Ljava/lang/Thread;",
    242         Dalvik_java_lang_VMThread_currentThread },
    243     { "getStatus",      "()I",
    244         Dalvik_java_lang_VMThread_getStatus },
    245     { "holdsLock",      "(Ljava/lang/Object;)Z",
    246         Dalvik_java_lang_VMThread_holdsLock },
    247     { "interrupt",      "()V",
    248         Dalvik_java_lang_VMThread_interrupt },
    249     { "interrupted",    "()Z",
    250         Dalvik_java_lang_VMThread_interrupted },
    251     { "isInterrupted",  "()Z",
    252         Dalvik_java_lang_VMThread_isInterrupted },
    253     { "nameChanged",    "(Ljava/lang/String;)V",
    254         Dalvik_java_lang_VMThread_nameChanged },
    255     { "setPriority",    "(I)V",
    256         Dalvik_java_lang_VMThread_setPriority },
    257     { "sleep",          "(JI)V",
    258         Dalvik_java_lang_VMThread_sleep },
    259     { "yield",          "()V",
    260         Dalvik_java_lang_VMThread_yield },
    261     { NULL, NULL, NULL },
    262 };
    

    源码中第242行找到对应的名字,其实现就在第44行。

    这个方法不是很准确,要靠经验来判断搜出来的代码是否是自己要找的,下一个方法可以较准确的查找。

    方法二

    还是找VMThread.java的currentThread函数,找多了会发现,每一个native方法的C++实现, 都映射为一个C++中的方法名。

    C++的名字一般都是包名_类名_方法名,比如currentThread的C++名字就肯定包含“java_lang_VMThread_currentThread”,所以直接搜索即可。

    grep -rns "java_lang_VMThread_currentThread" ./*
    
    如果说我的文章对你有用,只不过是我站在巨人的肩膀上再继续努力罢了。
    若在页首无特别声明,本篇文章由 Schips 经过整理后发布。
    博客地址:https://www.cnblogs.com/schips/
  • 相关阅读:
    Java swing生成图片验证码
    Spring关于事物的面试题
    SSM跨域拦截设置
    servlet实现图片上传工具类
    layUI框架table.render发送请求,数据返回格式封装
    @PathVariable、@requestParam 和@param的区别
    @GetMapping、@PostMapping、@PutMapping、@DeleteMapping、@PatchMapping用法
    Java之数组的拷贝
    Linux之磁盘分区和挂载
    Linux之磁盘情况查询
  • 原文地址:https://www.cnblogs.com/schips/p/how_to_find_the_instantiation_of_c-cpp_about_java_native.html
Copyright © 2020-2023  润新知