Android - NDK 动态注册方法

NDK中动态注册JNI方法。

本文链接

Java中定义了native方法后,在C/C++中使用JNI_OnLoad函数来注册相应的方法。

一般做法如下:

  • Java中定义native方法,确定Java文件的包名和路径
  • 编写C/C++文件
    • 实现相应的jni方法
    • 根据Java文件路径和方法签名确定JNINativeMethod
    • 实现JNIEXPORT int JNICALL JNI_OnLoad(JavaVM *vm,void *reserved)方法
      • 注册jni方法 RegisterNatives
  • 编译生成so文件
  • Java中加载so库文件
  • Java中调用native方法

相比于之前的静态注册,这里没有用javah生成头文件。

关于查询Java方法签名

关于查询Java方法签名,可以使用javap -s命令查询相应的class文件。

例如查看DynamicJNI.java的方法签名,先编译出DynamicJNI.class文件,再查询。

$ javap -s ./build/intermediates/classes/debug/com/rustfisher/appndkground/jni/DynamicJNI.class
Compiled from "DynamicJNI.java"
public class com.rustfisher.appndkground.jni.DynamicJNI {
  public com.rustfisher.appndkground.jni.DynamicJNI();
    descriptor: ()V

  public static native java.lang.String getHello();
    descriptor: ()Ljava/lang/String;

  public static native int meaningOfTheUniverse();
    descriptor: ()I

  static {};
    descriptor: ()V
}

查询得知getHello()的方法签名为()Ljava/lang/String
meaningOfTheUniverse()方法签名为()I

如果方法签名错了,编译能通过,但运行时会报NoSuchMethod异常

动态注册JNI方法示例

主要文件:

  • dynamic_jni.cpp 方法实现文件
  • DynamicJNI.java jni接口

DynamicJNI.java中定义native方法。ndkground是模块名称。

public class DynamicJNI {
    static {
        System.loadLibrary("ndkground");
    }

    public static native String getHello();

    public static native int meaningOfTheUniverse();

}

文件路径是"com/rustfisher/appndkground/jni/DynamicJNI",这个路径确定后一般不再改动。

dynamic_jni.cpp实现相关的方法

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <jni.h>

#define JNI_REG_CLASS "com/rustfisher/appndkground/jni/DynamicJNI" // path of Java file

JNIEXPORT jstring JNICALL get_hello(JNIEnv *env, jclass clazz) {
    return env->NewStringUTF("hello from jni");
}

JNIEXPORT jint JNICALL meaning_of_the_universe(JNIEnv *env, jclass clazz) {
    return 42;
}

static JNINativeMethod g_methods[] = {
    { "getHello", "()Ljava/lang/String;", (void*)get_hello},
    { "meaningOfTheUniverse", "()I", (void*)meaning_of_the_universe},
};

// must define this function
JNIEXPORT int JNICALL JNI_OnLoad(JavaVM *vm,void *reserved) {
  JNIEnv *env;
  if (vm->GetEnv((void **) &env,JNI_VERSION_1_6) != JNI_OK) {
    return JNI_ERR;
  }

  jclass javaClass = env->FindClass(JNI_REG_CLASS);
  if (javaClass == NULL){
    return JNI_ERR;
  }

  int method_count = sizeof(g_methods) / sizeof(g_methods[0]);
  if (env->RegisterNatives(javaClass, g_methods, method_count) < 0) {
    return JNI_ERR;
  }

  return JNI_VERSION_1_6;
}

这里使用Cygwin执行ndk-build来编译生成so文件。

调用动态注册的jni方法 DynamicJNI.getHello()

相应代码参见 https://github.com/RustFisher/android-Basic4/tree/master/appNdkGround

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容

  • 文|孟永辉 移动互联网浪潮的逐步退却正在将家装市场发展带入到一个全新阶段。同"互联网+"时代的轻松上马,后移动互联...
    孟永辉阅读 239评论 0 0
  • 只是因为《解忧杂货铺》书名而认识他。 也许还因为这个日本名字比较好记吧。 看小说、电影我总不是一个顾尾的人,结局于...
    牧羊Max阅读 372评论 0 1
  • 一名高速交警大队长有感而发——让你了解真实的交警,温州徐雪芬律师采访文字,我感觉简直是狡辩,现在的交警之所以警民关...
    日头去私长翻转阅读 158评论 0 0