下面是在ubuntu 下java jni調用C語言動态連結庫的具體操作步驟。
1、建立一個Java程式(TestJNI.java)定義原生的c函數。
2、用javac編譯TestJNI.java生成TestJNI.class。用javah帶-jni參數編譯TestJNI.class生成TestJNI.h檔案,該檔案中 定義了c的函數原型。在實作c函數的時候需要。
3、建立Hello.c,實作TestJNI.h定義的函數。
4、編譯Hello.c生成libgoodlucky.so。
5、在java虛拟機運作java程式TestJNI。
1、Test.java 源檔案
public class TestJNI {
static{
System.loadLibrary("goodlucky");
}
public native void set(int value);
public native int get();
public static void main(String[] args) {
TestJNI td=new TestJNI();
td.set(10);
System.out.println(td.get());
}
}
2、javac TestJNI.java
javah -jni Test
生成了TestJNI.h檔案
内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TestJNI */
#ifndef _Included_TestJNI
#define _Included_TestJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: TestJNI
* Method: set
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_TestJNI_set
(JNIEnv *, jobject, jint);
/*
* Class: TestJNI
* Method: get
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_TestJNI_get
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
3、 TestJNI.c,内容如下
#include <stdio.h>
#include "TestJNI.h"
int i=0;
JNIEXPORT void JNICALL Java_TestJNI_set
(JNIEnv * env, jobject obj, jint j)
{
i=j;
}
JNIEXPORT jint JNICALL Java_TestJNI_get
(JNIEnv * env, jobject obj)
{
return i;
}
4、
生成:對象檔案TestJNI.o
gcc -Wall -fPIC -c TestJNI.c -I./ -I/home/abc/jdk1.7/include -I/home/abc/jdk1.7/include/linux
生成動态庫libgoodlucky.so 注意這裡的goodlucky 對應TestJNI.java中goodlucky。并且這裡要以lib開頭命名動态庫.-Wall 顯示錯誤和警告提示 -I(不是l,就是這個害死我了,汗)後面是 jni.h,jni_md.h的路徑
gcc -Wall -rdynamic -shared -o libgoodlucky.so TestJNI.o
上面的兩條指令等價于下面的指令:
gcc -Wall -fPIC -I./ -I/home/abc/jdk1.7/include -I/home/abc/jdk1.7/include/linux -shared -o libgoodlucky.so TestJNI.c
編譯器選項-fpic和連結器選項-shared
修改.bash_profile檔案,配置環境變量,由于生成的.so檔案在目前目錄下,故
.bash_profile檔案設定如下
export LD_LIBRARY_PATH=./
或者把生成的.so檔案放到/usr/lib目錄下也可以。
5、java TestJNI
進階:
1、在第四步中,編寫makefile檔案
内容如下:
libgoodlucky.so:TestJNI.o makefile
gcc -Wall -rdynamic -shared -o libgoodlucky.so TestJNI.o
TestJNI.o:TestJNI.c TestJNI.h
gcc -Wall -c TestJNI.c -I./ -I/home/abc/jdk1.7/include -I/home/abc/jdk1.7/include/linux
cl:
rm -rf *.o *.so
格式如下:
一個 makefile 主要含有一系列的規則,如下:
A: B
(tab)<command>
(tab)<command>
每個指令行前都必須有tab符号。
具體可參考:http://goodcandle.cnblogs.com/archive/2006/03/30/278702.html
參考見:
http://watershitter.iteye.com/blog/477615#comments
http://lwjlaser.iteye.com/blog/779270
http://blog.csdn.net/kangkanglou/article/details/5807787
思考若是java檔案帶有包路徑呢?可以去動手做做