参数传递
- Java传String到底层,利用GetStringUTFChars转换成字符指针数组,该过程需要分配内存,要进行一个判空操作:
同时需要释放上面操作所消耗的内存。 - 操作数组,env->getArrayElemetns 返回java数组的一个拷贝,优良的VM,会返回指向Java数组的一个直接的指针,并标记该内存区域,不允许被GC。
- 对象数组,使用Get/SetObjectArrayElement操作,对象数组只针对单个的元素,不提供类似Region的区域性操作。
- 获得类字节码:getObjectClass,FindClass
- 获得类的字段,getFieldID
- 获得某个对象的字段的值,getObjectField
添加日志
#include <android/log.h>
#define LOGD(…) android_log_print(ANDROID_LOG_DEBUG,”TAG”,VA_ARGS__)
类型签名
基本类型签名
函数签名,java支持函数重载,虽然参数不一样,但是方法名一样,因此jni层需要通过方法名和方法签名来唯一确定函数的调用
(参数类型签名) + 返回值类型签名,对于没有返回值的,用V表示
String test() Ljava/lang/String;
int test(int i ,Object object) (ILjava/lang/Object;)I
void set(byte[] b) ([B)V
c语言的指针
- 在声明指针中,“*”号表示所声明的变量是个指针
- 在指针使用时,“*”号表示操作指针所指向的内存空间中的值
- 当*p放在等号左边时,相当于给内存赋值
当*p放在等号右边时,相当于从内存取值
1
2
3
4
5int i = 3,j = 0;
int *p = NULL;
p = &i; //p指向i所在的内存
*p = 5; //将p所指向的内存里的值修改为5,此时i的值也为5
j = *p; //将p所指向的内存空间的值赋值给j如果函数的参数里包含指针,进入函数系统会重新创建一个指针变量,与该参数指向相同的变量,因此如果要想在函数内部想修改指针的指向,就要用到二级指针
定位jni运行时的错误日志(Fatal signal 11 (SIGSEGV))
- 命令行输入: adb logcat > log.txt,将会在项目更目录写入log.txt文件
- 再在命令行输入:ndk-stack -sym app/build/intermediates/cmake/debug/obj/armeabi-v7a -dump ./log.txt