Mac OS X Yosemite 10.10.5java
java version "1.8.0_51"c++
简单介绍什么是JNI(Java Native Interface)。经过一个 HelloWorld 小程序,实现经过 Java 调用 C++ 打印 “ Hello Wolrd ” 。编程
在编程领域, JNI (Java Native Interface,Java本地接口)是一种编程框架,使得 Java 虚拟机中的 Java 程序能够调用本地应用/或库,也能够被其余程序调用。 本地程序通常是用其它语言( C 、 C++ 或汇编语言等)编写的, 而且被编译为基于本机硬件和操做系统的程序。小程序
定义摘自维基百科。简而言之,经过JNI可使 Java 程序和 C++ 程序直接通讯交互,不须要经过
如 .exe 等可执行文件流的方式去实现的交互。bash
光说概念其实可能也是看得云里雾里,不如直接就用一个实例来更加直观的了解JNI编程吧。如今咱们来写一个简单的 HelloWorld 小程序框架
首先建立一个 JniTest.java 文件 , 键入以下代码保存便可函数
public class JniTest { //导入lib文件 static { System.loadLibrary("jnitest"); } public JniTest() { //init() } // 调用 c++ 代码的函数 public native void printHelloWorld(); public static void main(String[] args) { new JniTest().printHelloWorld(); } }
接着在终端控制台,执行操作系统
javac JniTest.java
若成功执行就会生成相应的 JniTest.class 文件。接着执行命令行
javah JniTest
若成功执行就会生成 JniTest.h 文件。文件里已经根据咱们的 java 代码自动生成了相应的 c++ 代码,代码以下:code
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class JniTest */ #ifndef _Included_JniTest #define _Included_JniTest #ifdef __cplusplus extern "C" { #endif /* * Class: JniTest * Method: printHelloWorld * Signature: ()V */ JNIEXPORT void JNICALL Java_JniTest_printHelloWorld (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
那一长串以 JNIEXPORT 开头的函数就是咱们的函数接口。接着咱们再建立一个相应的 JniTest.cpp 文件 ,实现 .h 中的函数,记得要包含 .h 头文件。
#include <jni.h> #include "JniTest.h" #include <stdio.h> JNIEXPORT void JNICALL Java_JniTest_printHelloWorld (JNIEnv *, jobject) { printf("HelloWorld\n"); }
到这里咱们的主要代码编写就已经完成啦。但要让它跑起来还须要一点其余的操做。咱们首先要编译.cpp文件,这里能够直接在命令行使用 g++ -c JniTest.cpp
命令。可是此时这么键入是会报错的,它会提示:
JniTest.cpp:2:10: fatal error: 'jni.h' file not found #include <jni.h> ^ 1 error generated.
由于默认的头文件的搜索路径上是没有 jni.h文件的。咱们先得找到 jni.h文件在哪里。MacOS下,它的文件路径在 /Library/Java/JavaVirtualMachines/jdk1.8.0_51.jdk/Contents/Home/include (根据JDK版本不一样,须要修改中间jdk文件夹的名字,不过最开始的 /Library/Java/JavaVirtualMachines/ 通常是不会变的)除了 jni.h 以外,我么还须要 jni_md.h 它就在上述的include文件下的 darwin
文件下,咱们能够先在.cpp文件的目录下建立 include 文件夹,而后把上述的两个文件拷进去。接着执行
g++ -c JniTest.cpp -I ./include
若成功就会生成JniTest.o的目标文件,接着再执行
g++ -dynamiclib -o libjnitest.jnilib JniTest.o
就会生成libjnitest.jnilib文件,注意! 生成的文件名命名必定要是 lib + "java中读取的库文件名(如jnitest)" + .jnilib 不然java载入库文件将会失败!而后咱们在终端键入
java JniTest
就会看到终端打印出HelloWorld
了 ! 咱们的Hello World小程序就完成啦!