今天看了《core java卷二》的第十二章,在自己写代码的时候还是踩到了一些坑,因此在这里记录一下。
1、创建java类,建议不要加包名,省的后面找不到类(我之前加了包名,导致后面各种找不到或无法加载主类
。。)
public class HelloNative {
public static native void greeting();
static {
System.loadLibrary("hellonative");
}
public static void main(String[] args) {
HelloNative.greeting();
}
}
greeting方法就是我们要用C语言实现的方法。System.loadLibrary用于加载动态链接库。
2、编译这个类。
javac HelloNative.java
3、调用javah来生成头文件HelloNative.h
javah -jni HelloNative
HelloNative.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloNative */
#ifndef _Included_HelloNative
#define _Included_HelloNative
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloNative
* Method: greeting
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloNative_greeting
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
4、在HelloNative.c中给出函数的实现代码。
HelloNative.c
#include "HelloNative.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_HelloNative_greeting(JNIEnv * env, jclass jcl){
printf("Hello Native !\n");
return;
}
5、将C代码编译到动态链接库中。
gcc -dynamiclib -I /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/include HelloNative.c -o libhellonative.jnilib
其中,JDK的目录各位读者请自行调整。
gcc的-I选项指定寻找头文件的目录,主要是由于HelloNative.h中有一行
#include <jni.h>
,而jni.h这个文件就在
/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/include
目录下面。
同理,由于jni.h里面有一行#include "jni_md.h"
,
如果/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/include
目录下面没有jni_md.h,则会报下面错误:
Cannot open include file: 'jni_md.h': No such file or directory
这时候把jni_md.h拷贝到
/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/include
目录里面即可。
gcc编译成功后,就会得到libhellonative.jnilib
这个文件。
在HelloNative.java文件中,有一行代码:
System.loadLibrary("hellonative");
就是用来加载libhellonative.jnilib
的。
注意:在执行gcc命令时,-o libhellonative.jnilib
中,hellonative前面的lib不可以缺少!?。。ㄎ揖鸵蛭雎粤苏飧?,网上查了好久的才发现,都是泪啊。。)
否则,会报no XXX in java.library.path
错误。
6、执行java HelloNative
,打印Hello Native !
,调用成功~