Linux下JNI的demo
Linux下JNI的demo
java访问C/C++有6步1.写java文件
2.编译java生成class
3.生成C/C++头文件。
4.写C/C++文件
5.编译生成dll(Window下)或so文件
6.运行java程序
下面介绍ubutun下一个JNI例子
1.编写Sample1.java文件:
- public class Sample1
- {
- public native int intMethod(int n);
- public native boolean booleanMethod(boolean bool);
- public native String stringMethod(String text);
- public native int intArrayMethod(int[] intArray);
- public static void main(String[] args)
- {
- System.loadLibrary("Sample1");
- Sample1 sample = new Sample1();
- int square = sample.intMethod(5);
- boolean bool = sample.booleanMethod(true);
- String text = sample.stringMethod("JAVA");
- int sum = sample.intArrayMethod(
- new int[]{1,1,2,3,5,8,13} );
- System.out.println("intMethod: " + square);
- System.out.println("booleanMethod: " + bool);
- System.out.println("stringMethod: " + text);
- System.out.println("intArrayMethod: " + sum);
- }
- }
一。上面的方法都用到了native关键字。
二。System.loadLibrary("Sample1");这句中"Sample1"是我们在第5步中得到的库的名字,在window下是"Sample1.dll",在unix下要加前缀"lib",即"libSample1.so"。
2.编译java文件:
javac Sample1.java
无错生成Sample1.class文件
3.生成C/C++头文件
javah Sample1
生成Sample1.h
使用命令 cat Sample1.h 查看,内容为:
- /* DO NOT EDIT THIS FILE - it is machine generated */
- #include <jni.h>
- /* Header for class Sample1 */
- #ifndef _Included_Sample1
- #define _Included_Sample1
- #ifdef __cplusplus
- extern "C" {
- #endif
- JNIEXPORT jint JNICALL Java_Sample1_intMethod
- (JNIEnv *, jobject, jint);
- JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod
- (JNIEnv *, jobject, jboolean);
- JNIEXPORT jstring JNICALL Java_Sample1_stringMethod
- (JNIEnv *, jobject, jstring);
- JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod
- (JNIEnv *, jobject, jintArray);
- #ifdef __cplusplus
- }
- #endif
- #endif
4.编写C/C++代码
Sample1.c:
- #include "Sample1.h"
- #include <string.h>
- JNIEXPORT jint JNICALL Java_Sample1_intMethod
- (JNIEnv *env, jobject obj, jint num) {
- return num * num;
- }
- JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod
- (JNIEnv *env, jobject obj, jboolean boolean) {
- return !boolean;
- }
- JNIEXPORT jstring JNICALL Java_Sample1_stringMethod
- (JNIEnv *env, jobject obj, jstring string) {
- const char *str = (*env)->GetStringUTFChars(env, strin
- char cap[128];
- strcpy(cap, str);
- (*env)->ReleaseStringUTFChars(env, string, str);
- return (*env)->NewStringUTF(env, strupr(cap));
- }
- JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod
- (JNIEnv *env, jobject obj, jintArray array) {
- int i, sum = 0;
- jsize len = (*env)->GetArrayLength(env, array);
- jint *body = (*env)->GetIntArrayElements(env, array, 0
- for (i=0; i<len; i++)
- { sum += body[i];
- }
- (*env)->ReleaseIntArrayElements(env, array, body, 0);
- return sum;
- }
- void main(){}
Sample1.cpp:
- #include "Sample1.h"
- #include <string.h>
- NIEXPORT jint JNICALL Java_Sample1_intMethod
- (JNIEnv *env, jobject obj, jint num) {
- return num * num;
- }
- JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod
- (JNIEnv *env, jobject obj, jboolean boolean) {
- return !boolean;
- }
- JNIEXPORT jstring JNICALL Java_Sample1_stringMethod
- (JNIEnv *env, jobject obj, jstring string) {
- const char *str = env->GetStringUTFChars(string, 0);
- char cap[128];
- strcpy(cap, str);
- env->ReleaseStringUTFChars(string, str);
- return env->NewStringUTF(strupr(cap));
- }
- JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod
- (JNIEnv *env, jobject obj, jintArray array) {
- int i, sum = 0;
- jsize len = env->GetArrayLength(array);
- jint *body = env->GetIntArrayElements(array, 0);
- for (i=0; i<len; i++)
- { sum += body[i];
- }
- env->ReleaseIntArrayElements(array, body, 0);
- return sum;
- }
- void main(){}
两个差别就是JNIEnv这个类
C中使用 jsize len = (*env)->GetArrayLength(env,array);
C++中使用 jsize len = env->GetArrayLength(env,array);
5.生成共享库文件
编译Sample1.c文件
gcc -fPIC -D_REENTRANT -I/usr/lib/java/include -I/usr/lib/java/include/linux -c Sample1.c
编译用到了jdk include中jni.h,include/linux中jni_md.h两个头文件
/usr/lib/java/include 是jin.h路径
/usr/lib/java/include、linux 是jni_md.h路径
此时生成Sampel.o文件
运行:
gcc -shared Sample1.o -o libSample1.so
生成libSample1.so
6.运行java程序
libSample1.so文件拷贝到java的加载库LD_LIBRARY_PATH指向的路径中:
如果没有足够权限,可以这样:
(1).在/home下建立一个用来存放.so库文件的目录,比如/home/xxx/lib
(2).把libSample1.so文件拷贝到该目录下
(3).运行:export LD_LIBRARY_PATH=/home/xxx/lib (只在当前shall下有效...)
现在运行java Sample1
一切正常后,可以看到运行結果输出:
intMethod: 25
booleanMethod: false
stringMethod: JAVA
intArrayMethod: 33
完成第一个JNI程序。
评论暂时关闭