Java操作:
定义函数(关键字native): public native void FunctionName(byte arglist1[], char arglist2[], .....);
Load库文件 :
1. System.loadLibrary("Name") 加载在library.path下Name.dll文件,注意linux下.so文件的命名格式是 libName.so,仍然加载("Name")而不是("libName")
2. System.load("PATH/LibName.dll") 加载在绝对路径下Name.dll
javac ClassName.java 生成class文件
例:javac JniCase.java
javah Package.ClassName 生成Package_Class.h文件
例:javah jni.test.JniCase
java Package.ClassName 执行程序 -Djava.library.path=指定lib目录
例:java jni.test.JniCase
例子JniCase.java:
package jni.test;
public class JniCase {
public native int CFunction(byte datB[], char datC[], int len);
public static void main(String[] args) {
System.loadLibrary("TestLib");
JniCase sample = new JniCase();
final int DATA_SIZE = 128;
byte datB[] = new byte[DATA_SIZE];
char datC[] = new char[DATA_SIZE];
sample.CFunction(datB, datC, DATA_SIZE);
// Verification
int i;
for (i = 0 ; i < DATA_SIZE ; ++i) {
if (datB[i] % 16 != datC[i]) {
break;
}
}
if (i == DATA_SIZE) {
System.out.printf("Success!\n");
} else {
System.out.printf("Fail!\n");
}
}
}
C操作:
先将JDK下的include和include\win32导入lib工程下,引入javah生成的.h文件,在.h中有函数的定义。
例: g++ TestLib.cpp -O2 -shared -fPIC -m64 -o libTestLib.so
注意:1. 函数的命名格式: Java_Package_Path_FunctionName();
2. Java中char size 是2 Byte,Byte才是真正C中的char。
typedef unsigned short jchar;
例子TestLib.cpp:
#include "jni_test_JniCase.h"
JNIEXPORT jint JNICALL Java_jni_test_JniCase_CFunction
(JNIEnv *env, jobject obj, jbyteArray bArr, jcharArray cArr, jint _size) {
jbyte *cbArr = env->GetByteArrayElements(bArr, 0);
jchar *ccArr = env->GetCharArrayElements(cArr, 0);
for (int i = 0 ; i < _size ; ++i) {
ccArr[i] = i % 16;
cbArr[i] = i;
}
env->ReleaseByteArrayElements(bArr, cbArr, 0);
env->ReleaseCharArrayElements(cArr, ccArr, 0);
return 1;
}