老牛知点所以然-脱离开Android环境的JNI编程


作为一个资历尚浅的androider,JNI,或者叫做NDK开发,接触的不多.一直以来,心里想着做一件"酷酷"事情,即,脱离开安卓开发环境,码一码JNI的代码,剥去其略带神秘的面纱.
终于成行,记录下点滴:

关于标准输出

当我代码出现如下结构时:

	...
	JNI LOOP{
		printf("this is jni loop\n");
	}
	Java Loop {
		System.out.println("this is java loop");
	}
	...

代码执行时,并没有先输出JNI循环语句,而是Java循环语句输出完毕,JNI中输出语句才开始打印.我的内心是崩溃的,这尼玛是什么个情况?!突然我就意识到了,是两个调用标准输出的方法不同引起的,具体的说,printf是在"C空间"里的标准输出,而System.out.println是"Java空间"里的标准输出.不用怀疑代码的执行顺序,只不过是两者对标准输出设备操作时机未协调统一而已.
验证:将JNI层调用标准库函数的printf,替换成从JNI调用Java的System.out.println进行输出,成功验证了上述猜想.

不同JDK对jintarray内存空间的处理

我始终记得,在JDK1.6和1.7时,如下代码

void method(JNIEnv *env, jobject jo, jintArray jarr)
{
  int length = (*env)->GetArrayLength(env, jarr);
  int *arr = (*env)->GetIntArrayElements(env, jarr, JNI_FALSE);

   for (int i = 0; i < length; i++)
   {
     arr[i] += 10;
   }
}

操作的就是Java内存空间中的数组了,也就是每个数组元素在原来的基础上增加了10,然而这通操作在JDK1.8的前提下,并没有影响到Java内存空间中的数组,如果要直接改变Java内存中的数组元素,需要这么写:

  int length = (*env)->GetArrayLength(env, jarr);
  int *arr = (*env)->GetIntArrayElements(env, jarr, JNI_FALSE);

  int buffer[length];
  for (int i = 0; i < length; i++)
  {
    buffer[i] = arr[length - i - 1];
  }
  //采用这种方式,可以操作原java内存空间的数据
  (*env)->SetIntArrayRegion(env, jarr, 0, length, buffer);
Java对象的传递和成员变量的操作

这个就参考Java中反射是怎么做的就OK了.

jclass pClass = (*env)->FindClass(env,Java字节码的CanonicalName),CanonicalName中的`.`替换成'/'
jfieldID ageId = (*env)->GetFieldID(env, pClass, convert2charArray(env, stringAge), "I");最后一个参数是方法或者成员变量签名,通过`javap -s xxx.class`查看
jint iAge = (*env)->GetIntField(env, Java中类的对象, ageId);
示例Demo

这个Demo是一个Idea Maven项目,其中,脚本文件headergenerate.sh是用来生成JNI头文件用的,里面调用了javah命令,生成的头文件,直接输出到jni目录里,并将其中的<jni.h>替换成"jni.h";Makefile是C源文件编译成so的规则,将编译好的动态链接库,放置到lib目录里.另外,run之前,要配置library.path,也就是在IDEA的VM options上加上-Djava.library.path=你的路径/jniDemo/src/main/lib;
最后,奉上示例代码:
本文示例代码仓库

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值