JNI之------JNINativeMethod

文章出处:https://blog.csdn.net/shift_wwx/article/details/25808301

 

前言:之前的一篇(Android基础总结九:JNI详解)是结合实例的简单总结,这边总结一下JNINativeMethod。


1、JNINativeMethod 结构体的官方定义

typedef struct {  
    const char* name;  
    const char* signature;  
    void* fnPtr;  
} JNINativeMethod;

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

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

第三个变量fnPtr是函数指针,指向native函数。前面都要接 (void *)

第一个变量与第三个变量是对应的,一个是java层方法名,对应着第三个参数的native方法名字

 

示例:

 

static JNINativeMethod methods[] = {  
  { "printJNI", "()I",        (void*)printForTest},  
    
}; 

 

主要是第二个参数比较复杂:

括号里面表示参数的类型,括号后面表示返回值。

"()" 中的字符表示参数,后面的则代表返回值。例如"()V" 就表示void Fun();

"(II)V" 表示 void Fun(int a, int b);

 

2、第二个参数之基本类型

 

3、第二个参数之对象类型和数组类型

 

对象类型:以"L"开头,以";"结尾,中间用"/"隔开。如表第一行。

数组类型:以"["开头,如表第二行(n维数组的话,则前面就n个"[",如"[[[D"就表示double[ ][ ][ ])。

对象数组类型:就是上述两者结合,如表第三行。

 

4、举例

 

5、结合Media中的看看

static JNINativeMethod gMethods[] = {
    {
        "_setDataSource",
        "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",
        (void *)android_media_MediaPlayer_setDataSourceAndHeaders
    },

    {"_setDataSource",       "(Ljava/io/FileDescriptor;JJ)V",    (void *)android_media_MediaPlayer_setDataSourceFD},
    {"_setVideoSurface",    "(Landroid/view/Surface;)V",        (void *)android_media_MediaPlayer_setVideoSurface},
    {"prepare",             "()V",                              (void *)android_media_MediaPlayer_prepare},
    {"prepareAsync",        "()V",                              (void *)android_media_MediaPlayer_prepareAsync},
    {"_start",              "()V",                              (void *)android_media_MediaPlayer_start},
    {"_stop",               "()V",                              (void *)android_media_MediaPlayer_stop},
    {"getVideoWidth",       "()I",                              (void *)android_media_MediaPlayer_getVideoWidth},
    {"getVideoHeight",      "()I",                              (void *)android_media_MediaPlayer_getVideoHeight},
    {"seekTo",              "(I)V",                             (void *)android_media_MediaPlayer_seekTo},
    {"_pause",              "()V",                              (void *)android_media_MediaPlayer_pause},
    {"isPlaying",           "()Z",                              (void *)android_media_MediaPlayer_isPlaying},
    {"getCurrentPosition",  "()I",                              (void *)android_media_MediaPlayer_getCurrentPosition},
    {"getDuration",         "()I",                              (void *)android_media_MediaPlayer_getDuration},
    {"_release",            "()V",                              (void *)android_media_MediaPlayer_release},
    {"_reset",              "()V",                              (void *)android_media_MediaPlayer_reset},
    {"setAudioStreamType",  "(I)V",                             (void *)android_media_MediaPlayer_setAudioStreamType},
    {"setLooping",          "(Z)V",                             (void *)android_media_MediaPlayer_setLooping},
    {"isLooping",           "()Z",                              (void *)android_media_MediaPlayer_isLooping},
    {"setVolume",           "(FF)V",                            (void *)android_media_MediaPlayer_setVolume},
    {"native_invoke",       "(Landroid/os/Parcel;Landroid/os/Parcel;)I",(void *)android_media_MediaPlayer_invoke},
    {"native_setMetadataFilter", "(Landroid/os/Parcel;)I",      (void *)android_media_MediaPlayer_setMetadataFilter},
    {"native_getMetadata", "(ZZLandroid/os/Parcel;)Z",          (void *)android_media_MediaPlayer_getMetadata},
    {"native_init",         "()V",                              (void *)android_media_MediaPlayer_native_init},
    {"native_setup",        "(Ljava/lang/Object;)V",            (void *)android_media_MediaPlayer_native_setup},
    {"native_finalize",     "()V",                              (void *)android_media_MediaPlayer_native_finalize},
    {"getAudioSessionId",   "()I",                              (void *)android_media_MediaPlayer_get_audio_session_id},
    {"setAudioSessionId",   "(I)V",                             (void *)android_media_MediaPlayer_set_audio_session_id},
    {"setAuxEffectSendLevel", "(F)V",                           (void *)android_media_MediaPlayer_setAuxEffectSendLevel},
    {"attachAuxEffect",     "(I)V",                             (void *)android_media_MediaPlayer_attachAuxEffect},
    {"native_pullBatteryData", "(Landroid/os/Parcel;)I",        (void *)android_media_MediaPlayer_pullBatteryData},
    {"setParameter",        "(ILandroid/os/Parcel;)Z",          (void *)android_media_MediaPlayer_setParameter},
    {"getParameter",        "(ILandroid/os/Parcel;)V",          (void *)android_media_MediaPlayer_getParameter},
    {"native_setRetransmitEndpoint", "(Ljava/lang/String;I)I",  (void *)android_media_MediaPlayer_setRetransmitEndpoint},
    {"setNextMediaPlayer",  "(Landroid/media/MediaPlayer;)V",   (void *)android_media_MediaPlayer_setNextMediaPlayer},
    {"updateProxyConfig", "(Landroid/net/ProxyProperties;)V", (void *)android_media_MediaPlayer_updateProxyConfig},
};

如,

{"getParameter",        "(ILandroid/os/Parcel;)V",          (void *)android_media_MediaPlayer_getParameter},

就是代表java层函数void getParameter(int a , Parcel b),返回值是void,形参是init型和Parcel型
再如,

{"native_setRetransmitEndpoint", "(Ljava/lang/String;I)I",  (void *)android_media_MediaPlayer_setRetransmitEndpoint},

就代表java层函数int native_setRetransmitEndpoint(String a, int b),返回值是int,形参是String型和int型

 

 

 

  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
JNINativeMethod 是一个结构体,它包含了 JNI 方法的名称、签名和函数指针。在 JNI 中,Java 方法可以被映射到本地 C/C++ 函数,JNINativeMethod 就是用来描述这样的映射关系的。 在 Java 中,声明一个 native 方法时需要使用 native 关键字,例如: ``` public native int myNativeMethod(String arg); ``` 在 C/C++ 中,实现一个本地方法需要先定义一个与之对应的 JNINativeMethod 结构体,例如: ``` JNIEXPORT jint JNICALL Java_MyClass_myNativeMethod(JNIEnv *env, jobject obj, jstring arg) { // 实现本地方法的代码 } ``` 其中,Java_MyClass_myNativeMethod 就是一个符合 JNI 命名规范的函数名,它由三部分组成:Java、类名和方法名,中间用下划线 _ 分隔,最后需要带上 JNIEnv 和 jobject 两个参数。 如果有多个本地方法需要实现,可以定义一个 JNINativeMethod 数组,将所有的方法都描述出来,例如: ``` JNINativeMethod methods[] = { {"myNativeMethod", "(Ljava/lang/String;)I", (void*)Java_MyClass_myNativeMethod}, {"anotherNativeMethod", "()V", (void*)Java_MyClass_anotherNativeMethod}, // ... }; ``` 在初始化 JNI 时,需要调用 RegisterNatives 函数将 JNINativeMethod 数组注册到对应的 Java 类中,例如: ``` jclass cls = env->FindClass("MyClass"); env->RegisterNatives(cls, methods, sizeof(methods) / sizeof(methods[0])); ``` 其中,FindClass 函数用于获取 Java 类的 jclass 对象,RegisterNatives 函数用于将 JNINativeMethod 数组注册到对应的 Java 类中。 这就是将 Javanative 方法转换为 JNINativeMethod 的基本流程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

私房菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值