主参考文章: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 __cplusplus
extern "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 就能调用本地方法了。