HelloWord之JNI實例

閒來無事,所以自己練習了一遍jni實現,開始的時候程序一直找不到對應的lib庫,好生苦惱,後來發現是jni生成的lib庫沒有添加到對應的lib庫環境中,導致查找不到。。。。。

HelloWord.java
class HelloWorld {

    public native void displayHelloWorld();

    static {
        System.loadLibrary("hello");
    }

    public static void main(String[] args) {
        new HelloWorld().displayHelloWorld();
    }
}


javac HelloWorld.java //生成HelloWorld.class

javah -jni HelloWorld  //利用生成的class文件編譯成jni頭文件HelloWorld.h
大致內容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include </usr/lib/jvm/java-7-openjdk-amd64/include/jni.h>
/* Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorld
 * Method:    displayHelloWorld
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
  (JNIEnv * env, jobject obj);


#ifdef __cplusplus
}
#endif
#endif

編寫實現該頭文件的c文件:HelloWorldImpl.c
#include "/usr/lib/jvm/java-7-openjdk-amd64/include/jni.h"
#include "HelloWorld.h"

JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
  (JNIEnv * env, jobject obj){
    printf("Hello World!\n");
    return ;
}

然後將c文件編譯打包成so:

Linux中共享庫以so爲後綴(shared object),與Windows下的DLL類似,是在程序運行時動態連接。多個進程可以連接同一個共享庫。
以下以編譯mylib.c爲例講如何編譯.so文件。

首先,編譯HelloWorldImpl.c:

$gcc -c -fPIC -o HelloWorldImpl.o HelloWorldImpl.c

-c表示只編譯(compile),而不連接。-o選項用於說明輸出(output)文件名。gcc將生成一個目標(object)文件HelloWorldImpl.o。

注意-fPIC選項。PIC指Position Independent Code。共享庫要求有此選項,以便實現動態連接(dynamic linking)。

生成共享庫:

$gcc -shared -o hello.so HelloWorldImpl.o

庫文件以lib開始。共享庫文件以.so爲後綴。-shared表示生成一個共享庫。

這樣,共享庫就完成了。.so文件和.h文件都位於當前工作路徑(.)。


運行java HelloWorld,就可以看到我們打印的Hello world了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章