参考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内存布局

野指针
就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)指针变量在定义时如果未初始化,其值是随机的,指针变量的值是别的变量的地址,意味着指针指向了一个地址是不确定的变量,此时去解引用就是去访问了一个不确定的地址,所以结果是不可知的。
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
静态内部类,如图所示

如果加上
@JvmStatic
会在外部类生成静态方法,如图所示
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
反编译器

方法三:Android Studio工具查看字节码

方法四:Alt+Enter万能快捷键

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
网友评论