美文网首页
JNI开发流程

JNI开发流程

作者: 潇洒人生_cca2 | 来源:发表于2020-04-05 10:30 被阅读0次

    预编译

    C语言执行的流程

    1.编译:形成目标代码(.obj)

    2.连接:将目标代码与C函数库连接合并,形成最终的可执行文件

    3.执行

    预编译(预处理),为编译做准备工作,完成代码文本的替换工作

    头文件告诉编译器有这样一个函数,连接器负责找到这个函数的实现

    头文件只包含一次,防止重复引用:
    1.#ifndef #define #endif组合使用(老版本)
    2.#pragma once

    define指令

    1.定义标示

    ifdef __cplusplus 标识支持C++语法

    防止文件重复引入

    2.定义常数(便于修改与阅读)

    define MAX 100

    3.定义“宏函数”

    define jni(NAME) dn_com_jni_##NAME();NAME是参数,对于dn_com_jni_read函数来说,NAME就是read

    //webrtc JNI函数名称很长,也是JOW宏函数缩短函数名称

    void dn_com_jni_read(){
    }

    JNI(Java Native Interface)(Windows下)

    Java调用C/C++,C/C++调用Java的一套API

    1.编写native方法

    2.javah命令,生成.h头文件。

    3.复制.h头文件到CPP工程中

    4.复制jni.h和jni_md.h文件到CPP工程中(去jdk安装目录里可以找到这两个.h文件)

    5.实现.h头文件中声明的函数(C的函数名称:Java_完整类名_函数名)

    #include "jni.h"
    /* Header for class com_ccg_jni_JniTest */
    
    #ifndef _Included_com_ccg_jni_JniTest
    #define _Included_com_ccg_jni_JniTest
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_ccg_jni_JniTest
     * Method:    getStringFromC
     * Signature: ()V
     */
    JNIEXPORT jstring JNICALL Java_com_ccg_jni_JniTest_getStringFromC
      (JNIEnv *, jclass);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    

    C语言

    #include "com_ccg_jni_JniTest.h"
    
    //函数实现
    JNIEXPORT jstring JNICALL Java_com_ccg_jni_JniTest_getStringFromC
    (JNIEnv *env, jclass jcls){
        //JNIEnv 结构体指针
        //env二级指针
        //代表Java运行环境,调用Java中的代码
    
        //简单的实现
        //将C的字符串转为一个java字符串
        return (*env)->NewStringUTF(env,"C String");
    }
    

    C++

    #include "com_ccg_jni_JniTest.h"
    JNIEXPORT jstring JNICALL Java_com_ccg_jni_JniTest_getStringFromC
    (JNIEnv *env, jclass jcls){
        //JNIEnv 在C++中就是一个结构体的别名
        //env 在C++中一个结构体的一级指针
        return env->NewStringUTF("C String");
    }
    

    6.生成dll文件(动态库,最终文件不包含动态库,.a静态库包含在最终文件里)

    7.配置dll文件所在目录到环境变量(或者copy到工程根目录下)

    8.重启Eclipse

    分析JNIEnv

    在C中:
    JNIEnv 结构体指针别名
    env二级指针

    在C++中:
    JNIEnv 是一个结构体的别名
    env 一级指针

    1.为什么需要传入JNIEnv,函数执行过程中需要JNIEnv
    2.C++为什么没有传入? 因为C++this就代表了JNIEnv
    3.C++只是对C的那一套进行的封装,给一个变量赋值为指针,这个变量是二级指针(把指针赋值给指针)

    简写JNIEnv

    
    //JNIEnv结构体的指针别名
    typedef struct JNINativeInterface_* JNIEnv;
    
    //结构体
    struct JNINativeInterface_ {
        char* (*NewStringUTF)(JNIEnv*, char*);
    };
    
    //函数实现
    char* NewStringUTF(JNIEnv* env, char* str){
        //在NewStringUTF执行过程,仍然需要JNIEnv
        return str;
    }
    
    void main(){
        //实例化结构体
        struct JNINativeInterface_ struct_env;
        struct_env.NewStringUTF = NewStringUTF;
    
        //结构体指针
        JNIEnv e = &struct_env;
        
        //结构体的二级指针
        JNIEnv *env = &e;
    
        //通过二级指针调用函数
        char* str = (*env)->NewStringUTF(env,"abc");
    }
    
        
    

    相关文章

      网友评论

          本文标题:JNI开发流程

          本文链接:https://www.haomeiwen.com/subject/krdjlctx.html