[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类型 | 类型签名 |
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 |
相关文章推荐
- android 动态注册JNI函数过程源码分析
- Android Studio NDK 入门教程(8)--JNI动态注册本地方法
- android 动态注册JNI函数过程源码分析
- Android JNI静态和动态注册 、Java Reflect(C或C++层反射和JAVA层反射)、Java 可变参数(JNI实现)
- Android JNI开发(1)--JavaVM和 JNIEnv 动态注册本地方法
- JNI_onLoad 动态注册函数
- cocos2dx3.3 android工程 Jni调用java函数
- JavaSE JNI 动态注册本地方法(c语言实现native层)
- 经典的java/android下JNI编程教程
- Android JNI使用方法(“动态注册”)
- Android JNI动态注册Native 方法(实现IDA中改名)
- 【iOS-cocos2d-X 游戏开发之十三】详细讲解在Xcode中利用预编译并通过Jni调用Android的Java层代码(cocos2dx里访问调用Android函数)!
- 关于PHP-Zend framework2 框架 学习过程。 阅前须知: ZF2中的配置文件是可以静态文件配置来注册和通过相关函数动态注册。 1.EventManager(事件驱动),关于事件驱动,在ZF2相关资料没有详细说明,可以参考ANDROID的事件驱动,MFC的消息响应/事件驱动。
- android在JNI_OnLoad入口函数下断点动态调试so库
- Android(java)学习笔记173:BroadcastReceiver之 BroadcastReceiver静态注册(SD卡卸载或者安装案例)和 BroadcastReceiver动态注册注销
- JavaSE JNI 动态注册本地方法(c语言实现native层)
- 利用mallo动态申请的变量,跨函数访问(Android之JNI)
- Android 基于NDK的JNI开发 C调用java和java调用C的进阶教程
- Android Java调JS:WebView.loadUrl("javascript:functionName()") JS调Java:WebView注册JS函数
- [原创]Android 基于NDK的JNI开发 C调用java和java调用C的进阶教程