JNI开发技术归纳
来源:互联网 发布:网络诈骗罪到哪里报警 编辑:程序博客网 时间:2024/06/04 15:58
在Android开发中会遇到使用JNI的情况,JNI是Java Native Interface的缩写,即Java本地接口,通过JNI技术可以实现两点:
1)Java程序能够调用Native函数,Native一般指的是C/C++
2)Native函数能够调用Java层的方法
1.JNI注册JNI的注册分成两种:1)静态注册;2)动态注册
Java层实现调用Native函数的代码示例如下:
public class JniHelper{ static { System.loadLibrary("jni_helper"); } private static native void nativeFunc();}
其中jni_helper是jni层库libjni_helper.so去掉lib后的名字,是由程序运行时系统加载,带有native关键字的方法,说明此方法是native代码实现的,也就是说该方法在库libjni_helper.so中实现
所谓的注册,也就是将java层中的nativeFunc()对应到libjni_helper.so库中的实现上,将声明和实现联系起来
1)静态注册的流程一般是,先编写java层代码,将java代码编译成class文件,再使用java提供的javah工具生成一个JNI层头文件,例如:javah -o jni_helper packgename.JniHelper,packgename.JniHelper是class文件,生成一个名为jni_helper.h的头文件,其中Java层声明的nativefunc()方法在JNI头文件中会声明为JNIEXPORT void JNICALL Java_pack_age_name_JniHelper_nativeFunc(JNIEnv*, jclass);
之所以将packagename写成pack_age_name,是因为包名中的"."会转换成"_",此处仅作示例
最后,根据这个生成的JNI层头文件,对应实现native方法就可以了,在Java层调用Native函数的时候,系统会到JNI库libjni_helper.so中去找对应的方法,找到的话就会为Java层方法和库中的方法(即JNI头文件中那一长串的方法声明)建立起关联,这就是静态注册的方式
2)实际上android中大都用的是动态注册方式,这种方式下会用到一个结构体JNINativeMethod,在JNI层代码中会定义一个JNINativeMethod数组
static JNINativeMethod gMethod[] = { { "nativeFunc", //Java层方法声明 "()V", //函数签名 (void *)nativeFFFunc //JNI层对应的函数指针 } };
对应的注册函数如下:
int registerNativeMethod(JNIEnv * env, const char * className, const JNINativeMethod * gMethod, int numMethods){ jclass clazz; clazz = (*env)->FindClass(env, className); if((*env)->RegisterNatives(env, clazz, gMethods, numMethods)<0) { return -1; } return 0;}
调用JNIEnv的RegisterNatives函数,就能够动态注册这种Java层函数与Native函数的关联
最后还需要实现JNI_Onload函数,该函数在JNI库libjni_helper.so加载时会去调用,如果实现了该函数,则调用它,没有实现则略过,当然在静态注册的时候也可以实现该函数,完成一些初始化工作,JNI_Onload函数示例如下:
jint JNI_Onload(JavaVM* vm, void* reserved){ JNIEnv* env = NULL; jint result = -1; if(vm->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) { return result; } //动态注册JNI函数,className指明Java中的类,形如"com/example/JniHelper",包的"."由"/"代替 registerNativeMethod(JNIEnv* env, const char* className, const JNINativeMethod* gMethod, int numMethods); return JNI_VERSION_1_4; //这个必须有,否则会报错}2.数据类型转换
Java数据类型分为基本数据类型和引用数据类型两种
1)基本数据类型转换如下:
2)引用数据类型转换如下:
3.JNI类型签名
因为Java有函数重载的概念,所以单靠函数名不能区分函数,需要有签名,签名由参数类型和返回值组成,签名格式:
(参数1类型标识参数2类型标识......参数n类型标识)返回值类型标识
类型标识表:
String f() 的签名是()Ljava/lang/String;
int f(char c, int i)的签名是(CI)I
签名写起来麻烦,看起来也别扭,不过java有一个javap工具能帮我们生成签名信息,用法如:javap -s -p classfile, classfile是编译后的class文件,-s输出内部数据类型的签名信息,-p打印所有函数和成员的签名信息
- JNI开发技术归纳
- JNI 开发技术 (一)
- Android JNI技术, NDK开发
- JNI的数据类型归纳
- Windows Phone开发技术博文归纳终结篇
- 技术需求归纳
- 神经网络技术归纳(转载)
- nlp 文本技术归纳
- 最近android技术归纳
- Android技术归纳
- JNI技术
- JNI技术
- JNI技术
- JNI技术
- 浅谈JNI技术在嵌入式软件开发中的应用
- Java开发中什么情况下要用到JNI技术??
- 浅谈JNI技术在嵌入式软件开发中的应用
- Sharepoint开发问题归纳
- 判断三角形(反面教材)
- RabbitMQ (二)工作队列
- 建造者模式(Builder)
- SpringMVC之web.xml,了解必要配置项
- Velocity入门指南
- JNI开发技术归纳
- Myeclipse 6.6解决eclipse不编译java文件,创建任何类 都提示我 一个错误信息 creation of element failed
- 学习Discuz! X3.2记录:一个小提示,可以知道插件php文件语法出问题了
- 第四周,项目三,1随机数函数应用于游戏
- RabbitMQ (三) 发布/订阅
- Animation旋转的动画
- .xcodeproj目录中各文件作用及SVN/Git同步
- RabbitMQ (四) 路由选择 (Routing)
- linux内核sk_buff的结构分析