JNI笔记 JNI开发流程

来源:互联网 发布:淘宝购物车营销 编辑:程序博客网 时间:2024/05/16 12:03

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  //如果是定义的cpptypedef JNIEnv_ JNIEnv;  //结构体#else               //如果是定义的ctypedef const struct JNINativeInterface_ *JNIEnv;  //结构体的指针#endif

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

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

提升效率 保证代码安全

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

原创粉丝点击