天天看點

linux下java調用C

下面是在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檔案帶有包路徑呢?可以去動手做做