JNI相关
参考https://www.jianshu.com/p/4c890e23c021
通过命令让.java文件生成.h头文件
javac Hello.java
javah Hello
add_library生成库文件,生成的库文件位置app\build\intermediates\cmake\debug\obj
LLVM 的命名最早来源于底层语言虚拟机(Low Level Virtual Machine)的缩写。它是一个用于建立编译器的基础框架,以C++编写。
gcc/g++命令
参考https://www.runoob.com/w3cnote/gcc-parameter-detail.html
https://gcc.gnu.org/onlinedocs/gcc-9.3.0/gcc/Directory-Options.html#Directory-Options
gcc 与 g++ 分别是 gnu 的 c & c++ 编译器 gcc/g++ 在执行编译工作的时候,总共需要4步:
-
预处理,生成 .i 的文件[预处理器cpp]
-
将预处理后的文件转换成汇编语言, 生成文件 .s [编译器egcs]
-
有汇编变为目标代码(机器代码)生成 .o 的文件[汇编器as]
-
连接目标代码, 生成可执行程序 [链接器ld]
只激活预处理,编译,和汇编,也就是他只把程序做成obj文件
gcc -c hello.c
-fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。
gcc -I/usr/lib/jvm/java-11-openjdk-amd64/include -I/usr/lib/jvm/java-11-openjdk-amd64/include/linux -shared -fPIC -o abc.so native-lib.cpp
undefined reference to std::cout关于这个错误,使用g++代替gcc编译,gcc和g++的主要区别
-
对于 .c和.cpp文件,gcc分别当做c和cpp文件编译(c和cpp的语法强度是不一样的)
-
对于 .c和.cpp文件,g++则统一当做cpp文件编译
-
使用g++编译文件时,g++会自动链接标准库STL,而gcc不会自动链接STL
C++打印信息
#include <android/log.h>
#define TAG "JNI_LOG"
#define LOG(...) __android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__)
C内存布局
内存布局.png
野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)指针变量在定义时如果未初始化,其值是随机的,指针变量的值是别的变量的地址,意味着指针指向了一个地址是不确定的变量,此时去解引用就是去访问了一个不确定的地址,所以结果是不可知的。
JNI获取JAVA层String字符串
jboolean isCopy;
const char *str = env->GetStringUTFChars(a, &isCopy);
LOG("字符串:%s", str);
// 释放内存
env->ReleaseStringUTFChars(a, str);
kotlin查看对应的java代码
- 打开需要查看的kotlin文件
- Tools -> Kotlin -> Show Kotlin Bytecode
- 点击decompile即可反编译出对应的java代码
companion object和@JvmStatic
companion object会生成一个Companion静态内部类,如图所示
image.png
如果加上
@JvmStatic会在外部类生成静态方法,如图所示
image.png
Android Studio有关窗口的一些快捷键
Alt+1 打开Project窗口Alt+6 打开Logcat窗口Alt+F12 打开Terminal窗口Shift+Esc 关闭活动窗口Alt+Insert get/set方法Ctrl+Alt+Insert 当前目录新建文件Ctrl+Alt+V 提取局部变量Ctrl+Alt+F 提取全局变量Ctrl+Alt+M 提取方法方法签名
方法一:查表
| Java 类型 | 类型签名 |
|---|---|
| boolean | Z |
| byte | B |
| char | C |
| short | S |
| int | I |
| long | L |
| float | F |
| double | D |
| 类 | L全限定名;,比如String, 其签名为Ljava/lang/util/String; |
| 数组 | [类型签名, 比如 [B |
方法二:javap反编译器
image.png
方法三:Android Studio工具查看字节码
image.png
方法四:Alt+Enter万能快捷键
image.png
C++调用JAVA方法
jclass jclazz = env->GetObjectClass(thiz);
jmethodID methodId = env->GetMethodID(jclazz, "jobject", "()Ljava/lang/String;");
jstring aaa = static_cast<jstring>(env->CallObjectMethod(thiz, methodId));
const char *bbb = env->GetStringUTFChars(aaa, &isCopy);
LOG("Java方法返回:%s", bbb);
//释放内存
env->ReleaseStringUTFChars(aaa, bbb);
env->DeleteLocalRef(jclazz);
env->DeleteLocalRef(aaa);
JNI引用
参考https://www.cnblogs.com/fnlingnzb-learner/p/7372189.html