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步:

  1. 预处理,生成 .i 的文件[预处理器cpp]

  2. 将预处理后的文件转换成汇编语言, 生成文件 .s [编译器egcs]

  3. 有汇编变为目标代码(机器代码)生成 .o 的文件[汇编器as]

  4. 连接目标代码, 生成可执行程序 [链接器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++的主要区别

  1. 对于 .c和.cpp文件,gcc分别当做c和cpp文件编译(c和cpp的语法强度是不一样的)

  2. 对于 .c和.cpp文件,g++则统一当做cpp文件编译

  3. 使用g++编译文件时,g++会自动链接标准库STL,而gcc不会自动链接STL

C++打印信息

#include 
#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代码

  1. 打开需要查看的kotlin文件
  2. Tools -> Kotlin -> Show Kotlin Bytecode
  3. 点击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(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

你可能感兴趣的:(JNI相关)