CPU只是别0101这样的二进制文件,而xx.c或者xx.cpp文件需要编译成二进制文件才能运行。这个过程由编译器完成,有两个过程:
1、编译:
xxx.c/cpp--------->xx.obj(windows)或者xxx.o(linux)文件。
2、链接
xxx.o-------->xxxx.so或者xxx.exe。
项目工程中有很多C文件或者cpp文件和.h文件,把哪些链接到so里就需要一套编译规则。
Eclipse:
GNU编译器------------------>Android.mk文件的编译规则。
Android Studio
LLVM编译器----------------->CMakeList.txt文件的编译规则。
在开始探究原理之前带着几个问题:
1、java是JVM的堆栈空间而C/C++是在自己的native堆栈空间两个空间是怎么联系在一起的,做了哪些事情让JVM可以调用native的方法。
2、so库是怎么被加载的。
先写一个简单的android工程:
目录:
java代码:
C代码:
打印结果:diff和JNI。
探索在diff的方法中native到底有什么用呢?
在FileUtils.java文件中在写一个普通的方法
通过FileUtils的目录下javac FileUtils.java得到FileUtils.class文件
再使用javap命令反编译一下这个class文件
得到一堆的信息:
可以看出两个方法唯一不同(名字除外)就是flags中nativie方法多了一个ACC_NATIVE的标识。
从so的加载看起:
上传的图片模糊了......
理解JNI:
签名表: