Java使用JNI调用C/C++(windows和android平台)

来源:互联网 发布:芈月到底爱谁知乎 编辑:程序博客网 时间:2024/05/18 00:57

JNI的是Java Native interface(Java 本地接口)的缩写,可以通过JNI调用本地程序。

Java调用C/C++一般需要三步:
1.编写带有native方法的Java类,使用javac工具编译java类

Public JniTest{//声明本地方法Public native int add(int a, int b);}

2.使用javah来生成与native方法对应的头文件
包名和类名:
这里写图片描述
使用命令行工具,在src文件夹下,也就是包所存放的文件夹下执行
javah com.akuarius.jni.JniTest
执行完成后会在当前目录生成.h文件:
com_akuarius_jni_JniTest.h

内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_akuarius_jni_JniTest */#ifndef _Included_com_akuarius_jni_JniTest#define _Included_com_akuarius_jni_JniTest#ifdef __cplusplusextern "C" {#endif/* * Class:     com_akuarius_jni_JniTest * Method:    add * Signature: (II)I */JNIEXPORT jint JNICALL Java_com_akuarius_jni_JniTest_add  (JNIEnv *, jobject, jint, jint);#ifdef __cplusplus}#endif#endif

3.实现相应的头文件,并编译位动态链接库(windows下.dll,linux下.so)
3.1 使用vs编译dll,在windows的java运行环境下,使用vs生成dll供java调用。
根据上一步生成的.h文件中的函数名,来用C、C++实现对应的函数。
使用vs创建一个空项目,将上述头文件添加到工程中
创建C文件:

#include"com_akuarius_jni_JniTest.h"JNIEXPORT jint JNICALL Java_com_akuarius_jni_JniTest_add(JNIEnv *env, jobject obj, jint a, jint b){    return a + b;}

将项目的配置类型改为生成动态库:
这里写图片描述
然后编译。
编译可能会提示找不到jni.h文件,不用担心,只要安装了jdk,电脑中肯定是存在这个文件的。
这里写图片描述
这里写图片描述

将jni.h 和 jni_md.h拷贝到vc/include目录下,再次编译就成功了。
在release目录下会生成dll文件。
这里写图片描述
将该dll文件拷贝到环境变量path所包含的目录下,例如在配置jdk时添加的jdk的bin文件路径。
C:\Program Files\Java\jdk1.8.0_91\bin;

java调用本地库函数, 这里是windows下的java环境
System.loadLibrary(“JniDll”);
JniTest test = new JniTest();
Int ret Test.add(1,2);

3.2android平台使用ndk编译
Ndk是native developmet ki(本地开发工具)的缩写,能自动将so文件和java应用一起打包成apk。

3.2.1Ndk环境搭建
1.下载ndk,安装只需解压即可。
这里写图片描述
2.新建android工程,在android工程中新建jni文件夹
将上述的头文件和c文件拷贝进去,并且新建Android.mk用于编译生成.so文件。
这里写图片描述
同样会出现找不到jni.h头文件的问题
这里写图片描述
编辑Android.mk

LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:=JniDll.cpp  //注意这里是c还是cpp与文件保持一致LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)LOCAL_MODULE := JniDllinclude $(BUILD_SHARED_LIBRARY)

3.新建builder
(a)Project->Properties->Builders->New,新建一个Builder。
这里写图片描述
(b)在弹出的【Choose configuration type】对话框,选择【Program】,点击【OK】:
这里写图片描述
(c)在弹出的【Edit Configuration】对话框中,配置选项卡【Main】。
这里写图片描述
名称可以随意取,位置填写ndk-build.cmd的位置,工作目录填写android的项目路径。
(d)继续在这个【Edit Configuration】对话框中,配置选项卡【Refresh】
这里写图片描述
(e)继续在【Edit Configuration】对话框中,配置选项卡【Build options】
这里写图片描述
在指定资源中,选择jni目录。

执行项目->清理,就会在工程目录下生成一个obj文件夹,该文件夹中有libJniDll.so文件。
有时会没有.so文件,只有.o.d文件,需要重新指定NDK路径。
这里写图片描述
在程序中使用静态加载,同变量的声明在一起
再次执行项目构建即可
这里写图片描述

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

调用

    JniTest test = new JniTest();           System.out.printf("%d \n", test.add(1, 2));
0 0