JNI笔记 JNI开发流程

1 编写native方法

public class JniTest {

    public native static String getStringFromC();

    public static void main(String[] args) {

    }
}

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

1在src上右键然后选properties,然后选择拷贝

这里写图片描述

2打开cmd命令 cd到刚才的src目录下。
这里写图片描述

3 使用javah命令,并拷贝全类名
这里写图片描述

4 会提示找不到什么的类文件
这时需要在javah 后添加-jni。如果还是不行,那就添加classpath . 注意这里有个点。这样就可以了。
这里写图片描述
并可以看到.h的头文件
这里写图片描述

3 复制.h头文件到cpp工程

1 把之前生成的.h文件复制到cpp工程中
这里写图片描述

2 在cpp工程右键选择添加现有项
通过这样把刚才拷贝到工程中的.h文件添加到本工程中。
这里写图片描述

添加过来后会发现报红
添加过来后会发现报红

4 复制jni.h和jni_md.h
用同样的方式把jni.h也添加到工程中
这里写图片描述

把尖括号改成双引号
这里写图片描述

最后用同样的方式把jni_md.h也添加过来。这样就不报错了

5 实现.h文件中的函数

#include "com_yeliang_JniTest.h"


//函数实现
JNIEXPORT jstring JNICALL Java_com_yeliang_JniTest_getStringFromC(JNIEnv *env, jclass jcss){
    //将C的字符串转为一个java字符串
    (*env)->NewStringUTF(env,"C String");
}

6 生成dll动态文件
选中上面的源文件,右键选择属性 然后选则配置管理器 选择平台为X64
这里写图片描述

选中项目然后右键,选择属性,把配置类型改为动态库
这里写图片描述

运行后会看到生成的dll动态库
这里写图片描述

7 通过java调用C

1 加载动态库

static{
        System.loadLibrary("jni_study");
    }

2 配置dll文件所在目录到环境变量
这里写图片描述
或者通过直接把dll文件考到工程的根目录下。都可以加载到动态库的文件。
然后重启eclipse,因为新增加了环境变量。
3 调用native方法

public class JniTest {

    public native static String getStringFromC();

    public static void main(String[] args) {
        String text = getStringFromC();
        System.out.println(text);
    }

    //加载动态库
    static{
        System.loadLibrary("jni_study");
    }
}

打印结果

C String

整个过程就是在Java中会有一个native的方法,并加载了dll的动态库。java类会在动态库中找这个方法(方法名为:java_完整类名_函数名)。

可以看出C的函数名为:Java_完整类名_函数名

JNIEnv 相关解释
1 在C中JNIEnv是结构体指针
代表Jav运行环境。调用java中的代码。
转到声明后可以看到:

typedef const struct JNINativeInterface_ *JNIEnv;

在转到定义后可以看到

struct JNINativeInterface_ {
    void *reserved0;
    void *reserved1;
    void *reserved2;

    void *reserved3;
    jint (JNICALL *GetVersion)(JNIEnv *env);

    jclass (JNICALL *DefineClass)
      (JNIEnv *env, const char *name, jobject loader, const jbyte *buf,
       jsize len);
    jclass (JNICALL *FindClass)
      (JNIEnv *env, const char *name);

都是去调用java中的方法。并且可以看出env是一个二级指针。

2 在cpp中JNIEnv就是一个结构体别名
通过转到定义后可以看到。

#ifdef __cplusplus  //如果是定义的cpp
typedef JNIEnv_ JNIEnv;  //结构体
#else               //如果是定义的c
typedef const struct JNINativeInterface_ *JNIEnv;  //结构体的指针
#endif

env 在c++中是一个结构体的一级指针

总结
JNI(Java Native Interface)
Java调用C/C++,C/C++调用java的一套API。

提升效率 保证代码安全

.a静态库 全部都会包含在最终生的的exe文件里面。
.dll动态库 共享代码的方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值