您的位置:首页 > 移动开发 > Android开发

[Android]JNI动态注册Java函数教程

2014-12-26 18:44 369 查看
<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结果做处理
}


其中gMethods是函数声明:

static JNINativeMethod gMethods[] =
		{{ "native_XX", "()I",(void*)XX },其他函数}


对其说明一下,第一个参数是Java类中native函数的声明,第二个参数是函数的签名,括号内是函数的形参,后面跟的字母是返回值,因为Java具有多态性,确定一个函数的方式是唯一的函数名+形参+返回值,而(void*)是指在C语言中函数存放的类型,一般使用(void*),XX是在C语言中实现的函数名。

这样就实现了动态注册。

最后说一下在Java中的自动类怎么和C语言中的结构体对应起来。

一般的需求是在C层传输给Java层一个类,很简单,使用Object.

直接给Demo

Java层:
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(J***A层需要得到的包名+类名);//如 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 与 long 不是大写首字母, 分别是 Z 与 J, 类是L全限定类名, 数组是[元素类型签名;
-- 类的签名规则 :L + 全限定名 + ;三部分,
全限定类名以 / 分割;

Java类型类型签名
booleanZ
byteB
charC
shortS
intI
longJ
floatF
doubleD
L全限定类名
数组[元素类型签名
Java数据类型 C数据类型 JNI数据类型对比 : 32位 与 64位机器可能会有出入;

Java数据类型C本地类型JNI定义别名
intlongjint/jsize
long__int64jlong
bytesigned charjbyte
booleanunsigned charjboolean
charunsigned shortjchar
shortshortjshort
floatfloatjfloat
doubledoyblejdouble
object'

_jobjectjobject
数据类型表示方法 : int数组类型 jintArray , boolean数组 jbooleanArray ...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐