<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">最近在做关于JNI的项目,跟大家分享一些经验。</span>
关于在C层静态注册Java层的Demo网上已经有相当多的说明了。
这里是一个学习静态注册的很好的例子http://cherishlc.iteye.com/blog/1756762
可以先学习JNI的基本知识再学习下面的知识。
但是既然Java和C只是一个互调的过程,那么只要让JVM知道函数的对应关系就可以了。
这样就可以不需要那么长的函数名,而且以后对函数进行修改只需要修改头文件就行了,比较易于扩展和阅读。
直接开始。
首先说几点需要注意的:
1.在我们编写的C层的cpp文件时,它的会有生命周期函数加载的过程(我是这样理解称呼的)。
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
}
上面这个函数会在加载的开始调用,可以在这里方法体里进行Java函数的动态注册。
可以在这个函数内编写
registerNativeMethods(env,"包名+类名"){
int result = 0;
result = env->RegisterNatives(clazz, gMethods,sizeof(gMethods) / sizeof(gMethods[0]));
//这里对result结果做处理
}
static JNINativeMethod gMethods[] =
{{ "native_XX", "()I",(void*)XX },其他函数}
对其说明一下,第一个参数是Java类中native函数的声明,第二个参数是函数的签名,括号内是函数的形参,后面跟的字母是返回值,因为Java具有多态性,确定一个函数的方式是唯一的函数名+形参+返回值,而(void*)是指在C语言中函数存放的类型,一般使用(void*),XX是在C语言中实现的函数名。
这样就实现了动态注册。
最后说一下在Java中的自动类怎么和C语言中的结构体对应起来。
一般的需求是在C层传输给Java层一个类,很简单,使用Object.
直接给Demo
private int native_get(Object object){};
C层
//动态注册方法,第一个表示Java层的函数名,第二个表示(参数)返回值,第三个表示C层函数
static JNINativeMethod jMethods[] ={"native_get","(Ljava/lang/Object;)Ljava/lang/Object;",get}
//在JNI_OnLoad()中调用该动态注册函数
result = env->RegisterNatives(clazz, jMethods,
sizeof(jMethods) / sizeof(jMethods[0]));
//编写C函数
JNIEXPORT jobject JNICALL get(
JNIEnv *env, jclass thiz, jobject obj) {
jclass cls = env->FindClass(JAVA层需要得到的包名+类名);//如 com/csdn/Student
jfieldID issue = env->GetFieldID(cls, 类的成员变量名, 类型);//得到类的成员变量
env->SetObjectField(obj, issue, "赋值");//给成员变量复制
return obj;//返回对象
最后就可以在Java层调用改native函数获取到填充了值的object对象。
需要注意的是,必须在Java层传入一个新对象,C层只是负责给该对象填充值。
下面是一些类型在Java与C的互换
以下搬运自http://blog.csdn.net/shulianghan/article/details/18964835:
Java类型 | 类型签名 |
boolean | Z |
byte | B |
char | C |
short | S |
int | I |
long | J |
float | F |
double | D |
类 | L全限定类名 |
数组 | [元素类型签名 |
Java数据类型 | C本地类型 | JNI定义别名 |
int | long | jint/jsize |
long | __int64 | jlong |
byte | signed char | jbyte |
boolean | unsigned char | jboolean |
char | unsigned short | jchar |
short | short | jshort |
float | float | jfloat |
double | doyble | jdouble |
object' |
_jobject | jobject |