织梦CMS - 轻松建站从此开始!

罗索

当前位置: 主页>嵌入式开发>Android>

ANDROID JNINativeMethod

落鹤生 发布于 2012-04-11 13:33 点击:次 
Andoird 中使用了一种不同传统Java JNI的方式来定义其native的函数。其中很重要的区别是Andorid使用了一种Java和C++函数的映射表数组,并在其中描述了函数的参数和返回值。
TAG:

Andoird 中使用了一种不同传统Java JNI的方式来定义其native的函数。其中很重要的区别是Andorid使用了一种Java和C++函数的映射表数组,并在其中描述了函数的参数和返回值。这个数组的类型是JNINativeMethod,定义如下:

  1. typedef struct {   
  2.     const char* name;   
  3.     const char* signature;   
  4.     void* fnPtr;   
  5. } JNINativeMethod;   

第一个变量name是Java中函数的名字。

第二个变量signature,用字符串是描述了函数的参数和返回值。

第三个变量fnPtr是函数指针,指向C函数。

其中比较难以理解的是第二个参数,例如:

  1. "()V"      
  2. "(II)V"   
  3. "(Ljava/lang/String;Ljava/lang/String;)V"   

实际上这些字符是与函数的参数类型一一对应的。

“()” 中的字符表示参数,后面的则代表返回值。例如”()V” 就表示void Func();  “(II)V” 表示 void Func(int, int);

具体的每一个字符的对应关系如下:

字符   Java类型     C类型
V      void         void 
Z      jboolean     boolean 
I      jint         int 
J      jlong        long 
D      jdouble      double 
F      jfloat       float 
B      jbyte        byte 
C      jchar        char 
S      jshort       short

数组则以”[“开始,用两个字符表示:

[I     jintArray      int[] 
[F     jfloatArray    float[] 
[B     jbyteArray     byte[] 
[C     jcharArray     char[] 
[S     jshortArray    short[] 
[D     jdoubleArray   double[] 
[J     jlongArray     long[] 
[Z     jbooleanArray  boolean[]

上面的都是基本类型。如果Java函数的参数是class,则以”L”开头,以”;”结尾中间是用”/” 隔开的包及类名。而其对应的C函数名的参数则为jobject. 一个例外是String类,其对应的类为jstring。

Ljava/lang/String; String jstring 
Ljava/net/Socket; Socket jobject

如果JAVA函数位于一个嵌入类,则用$作为类名间的分隔符。

例如 “(Ljava/lang/String;Landroid/os/FileUtils$FileStatus;)Z”

注册JNI:

  1. static int registerMethods(JNIEnv* env) {   
  2.     static const charconst kClassName =   
  3.             "com/taner/ledservice/LedService";   
  4.     jclass clazz;   
  5.      
  6.     /* look up the class */   
  7.     clazz = env->FindClass(kClassName);   
  8.     if (clazz == NULL) {   
  9.         LOGE("Can't find class %s/n", kClassName);   
  10.         return -1;   
  11.     }   
  12.      
  13.     /* register all the methods */   
  14.     if (env->RegisterNatives(clazz, gMethods,   
  15.             sizeof(gMethods) / sizeof(gMethods[0])) != JNI_OK)   
  16.     {   
  17.         LOGE("Failed registering methods for %s/n", kClassName);   
  18.         return -1;   
  19.     }   
  20.      
  21.     /* fill out the rest of the ID cache */   
  22.     return 0;   
  23. }   

JNI_OnLoad:

  1. jint JNI_OnLoad(JavaVM* vm, void* reserved) {   
  2.     JNIEnv* env = NULL;   
  3.     jint result = -1;   
  4.     LOGI("JNI_OnLoad");   
  5.      
  6.     if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {   
  7.         LOGE("ERROR: GetEnv failed/n");   
  8.         goto fail;   
  9.     }   
  10.     assert(env != NULL);   
  11.      
  12.     if (registerMethods(env) != 0) {   
  13.         LOGE("ERROR: PlatformLibrary native registration failed/n");   
  14.         goto fail;   
  15.     }   
  16.      
  17.     /* success -- return valid version number */   
  18.     result = JNI_VERSION_1_4;   
  19.      
  20. fail:   
  21.     return result;   
  22. }   

Android JNI例子:

C:http://www.rosoo.net/a/201204/15924.html

C++:http://www.rosoo.net/a/201204/15925.html

这两种语言的JNI实现是不同的,留意这一点。

 

(sepnic)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201112/15562.html]
本文出处:CSDN博客 作者:sepnic 原文
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容