JNI基础

JNI基础

下一篇:Android JNI 开发环境配置

JNI 全称 Java Native Interface, 是java代码与native代码(一般是把c,c++这些直接编译成目标机器执行的代码加本地代码)实现互操作的接口, 是Java与c,c++的粘合剂

Java是运行在JVM上的语言, JVM运行的是Java的字节码,即中间码, 因此Java与调用本地代码,只能通过JNI

jni struct

JNI程序编译运行流程

  1. 声明Java的native 方法

  2. C++实现native方法的JNI函数

  3. 将所有JNI函数编译成动态链接库(linux为 .so, windows为 .dll, MacOS为 .dylib)

  4. 调用Java native方法前先加载库文件

    static{
       System.load(".so文件路径") // or System.loadLibrary("去掉lib的so文件名")
    }
  5. 调用native 方法

Java与c++ 的绑定的几种方法

1.用 javah 命令,生成对应的C语言头文件

javah -classpath D:\我的文档\workspace\PrepareForExam\bin  -jni
# -classpath <路径> 用于装入类的路径
# -jni 生成 JNI样式的头文件(默认)

2. 手写C++接口函数

extern "C" JNIEXPORT jint JNICALL Java_com_imi_sdk_jnitest_CameraPreviewFragment_stepTest(JNIEnv *env,jobject me,jint i);

注意

  • extern "C" 必须要有,否则会导致编译出来的函数找不到

  • 函数命名规则为: Java_{包路径+类名+方法名}, 方法名中每出现一个下划线, 要在下划线后面加数字1,如:

    extern "C" JNIEXPORT jint JNICALL Java_com_imi_sdk_jnitest_CameraPreviewFragment_step_1Test(JNIEnv *env,jobject me,jint i);

    对应Java的 com.imi.sdk.jintest.CameraPreviewFragment.step_Test()

  • 每个JNI函数的第一个参数都位JNIEnv *env, 第二个参数位jobject me(对象方法) 或者 jclass cls(静态方法)

  • JNI函数被调用时不会检测参数类型, 因此你写错参数位置的结果只会是莫名其妙的崩

3. 使用第三方工具生成

swig 是个很好的将c++的代码生成JNI接口的软件,你可以不用写一行JNI代码就能实现Java调用c++功能

4. 在JNI_OnLoad()中或者运行时动态注册JNI接口

static const JNINativeMethod gMethods[] = {
        {"getUrl", "()Ljava/lang/String;", (jstring*)getUrl},
        {"setData","([BI)V",(void*)setData}
};
// 
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){
    JNIEnv* env = NULL; //注册时在JNIEnv中实现的,所以必须首先获取它
    jint result = -1;
    if(vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) //从JavaVM获取JNIEnv,一般使用1.4的版本
      return -1;
    myClass = env)->FindClass(kClassName);
    if(myClass == NULL)
    {
      printf("cannot get class:%s\n", kClassName);
      return -1;
    }
    if(env->RegisterNatives(myClass,gMethods,sizeof(gMethods)/sizeof(gMethods[0]))<0)
    {
      printf("register native method failed!\n");
      return -1;
    }
    printf("--------JNI_OnLoad-----");
    return JNI_VERSION_1_4; //这里很重要,必须返回版本,否则加载会失败。
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值