主参考文章:https://segmentfault.com/a/1190000004610577
参考上面的文章走下来,是有点问题的。下面重新整理下这篇文章的步骤:
准备阶段
- 在
.java文件中创建native方法
public class MacJni {public native void sayHello();static {System.loadLibrary("macjni");}public static void main(String[] args) {MacJni macJni = new MacJni();macJni.sayHello();}}
javac编译.java文件,生成MacJni.class- 使用
javah MacJni生成MacJni.h头文件(注意javah MacJni别加后缀.class)
查看下MacJni.h内容:
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class MacJni */#ifndef _Included_MacJni#define _Included_MacJni#ifdef __cplusplusextern "C" {#endif/** Class: MacJni* Method: sayHello* Signature: ()V*/JNIEXPORT void JNICALL Java_MacJni_sayHello(JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif
注意第一行#include
待会要想办法找到这个头文件
- 创建一个
MacJni.c来实现MacJni.h头文件中定义的sayHello方法
#include <stdio.h>#include "MacJni.h"JNIEXPORT void Java_MacJni_sayHello(JNIEnv * env, jobject obj){printf("hello from jni");}
引入了 MacJni.h
编译C
我们刚刚创建了MacJni.c文件,现在我们要来编译它。
按照参考文章中的命令gcc -I/System/Library/Frameworks/JavaVM.framework/Headers -c MacJni.c 是找不到’jni.h’
会报错:

原因是 /System/Library/Frameworks/JavaVM.framework/Headers 这个路径不正确。
在我的Mac中它的地址是/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/include
你自己该如何找到它呢?
echo $JAVA_HOME找到Java的安装目录- 然后目标地址是
$JAVA_HOME/include
现在使用命令gcc -I /Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/include -c MacJni.c 来编译(注意,是-I 不是-L ),仍然会报错:

找不到jni_md.h。
怎么办?
找到jni_md.h,然后把它复制到$JAVA_HOME/include目录下。那么jni_md.h在哪呢 ?
在$JAVA_HOME/include/darwin目录下
所以使用命令复制一下:
sudo cp /Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/include/darwin/jni_md.h /Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/include
然后再使用上面的命令gcc -I /Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/include -c MacJni.c就可以了。
成功后会生成一个MacJni.o文件
接着使用命令gcc -dynamiclib -o libmacjni.jnilib MacJni.o 编译生成libmacjni.jnilib
上面两条红色的命令可以合并成一条命令:gcc -dynamiclib -I /Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/include MacJni.c -o libmacjni.jnilib
这里为什么是libmacjni,参考文章有提到:
在static中加载
native的类库macjni,注意JNI的动态库在linux上面的命名是.so文件,而在Mac OS上面的命名是.jnilib,类库的名字需要加上lib,也就是在Mac OS上面动态库的名称应该是libmacjni.jnilib
最后使用 java MacJni 就能调用本地方法了。
