一个本地文件的源码(C语言),重要的地方都已做了备注
注:jni中的基本类型可以在C/C++代码中直接使用,比如jint, jfloat等相当于C中的int, float。特殊类型需要转换为C/C++中对应的类型后才能在C/C++代码中使用。例如 jstring, jintArray等。C/C++中的特殊类型作为返回值时,需要先转换为jni中对应的类型。
#include <jni.h>
JNIEXPORT jbyteArray JNICALL Java_com_example_luct_demo3_util_SecurityAlgorithm_seed2Key
(JNIEnv *env, jclass obj, jint rounds, jintArray s, jintArray f, jint sal){
//定义一个有符号的byte数据类型
typedef signed char byte;
//声明接下来要用到的变量,C语言变量的使用规则所致
int j = 0, k = 0, i = 0, l =0;
int v0 = 0, v1 = 0, sum = 0, delta = 0x9E3779B9;
byte key[4];
//获取一个指向数组元素的指针,即将jintArray转换为C语言中的int数据(C++不能使用这样的方式)
jint *seed = (*env)->GetIntArrayElements(env, s, 0);
jint *f18c = (*env)->GetIntArrayElements(env, f, 0);
for (l = 1; l < sal; l++) {
for (j = 0; j < 4; j++) {
f18c[j] = (((0x0|f18c[j]) >> 3) & 0x1f) + (f18c[j] << 5);
}
}
v0 = ((seed[0] << 24)) | ((seed[1] << 16) & 0x00ff0000) | ((seed[2] << 8) & 0x00ff00) | (seed[3] & 0x00ff);
v1 = ~v0;
for (i = 0; i < rounds; i++) {
v0 += (((v1 << 4) ^ (((0x0|v1) >> 5) & 0x07ffffff)) + v1) ^ (sum + (f18c[(sum & 0x03)] & 0x00ff));
sum += delta;
v1 += (((v0 << 4) ^ (((0x0|v0) >> 5) & 0x07ffffff)) + v0) ^ (sum + (f18c[(((0x0|sum) >> 11) & 0x03)] & 0x00ff));
}
//释放数组元素的引用(C++不能使用这样的方式)
(*env)->ReleaseIntArrayElements(env, s, seed, 0);
(*env)->ReleaseIntArrayElements(env, f, f18c, 0);
//C中的(0x0|y)>> 2 相当于java中的无符号右移 y >>> 2
key[0] = ((0x0|v0) >> 24);
key[1] = ((0x0|v0) >> 16);
key[2] = ((0x0|v0) >> 8);
key[3] = v0;
//把C中自定义的byte数组转换成jbyteArray(C++不能使用这样的方式)
jbyte *by = (jbyte*)key;
jbyteArray jarray = (*env)->NewByteArray(env,4);
(*env)->SetByteArrayRegion(env, jarray, 0, 4, by);
return jarray;
}