看Java源码看到了native属性的函数,于是自己尝试一下JNI。
1. 在NativeTest类中声明native属性的函数
System.load()
用来装载库文件,参数为.so文件的绝对路径。
public class NativeTest {
static {
System.load("/home/ooc/test/java/NativeCPP.so");
}
public static native void NativePrint();
public static void main(String[] args) {
NativePrint();
}
}
2. 生成.h头文件
Shell命令 javah NativeTest
,这里NativeTest结尾不用加.java
生成 NativeTest.h
文件:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class NativeTest */
#ifndef _Included_NativeTest
#define _Included_NativeTest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: NativeTest
* Method: NativePrint
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_NativeTest_NativePrint
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
注意其中的函数签名,根据这个函数签名来写C/CPP的函数。
3. 实现c/cpp文件
NativeTest.c
#include <stdio.h>
#include "NativeTest.h" // 这里需要包含刚刚生成的头文件
JNIEXPORT void JNICALL Java_NativeTest_NativePrint(JNIEnv *env, jclass c) {
// 函数签名与 NativeTest.h 中的保持一致,区别是多了参数的变量名。
printf("Native mothod print!\n");
// 这里为函数的实现。
}
4. 编译一个动态链接库
Linux下编译生成 .so 文件,如果在Windows下则生成.dll文件。
Shell命令:g++ -fPIC -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -shared -o NativeCPP.so NativeTest.c
NativeCPP.so
为自己指定生成的文件名,NativeTest.c
是要编译的文件。
注意要加-shared
属性。
运行结果: