1. 程式人生 > 實用技巧 >java呼叫c程式簡單呼叫(2)

java呼叫c程式簡單呼叫(2)

手寫編譯太麻煩了,推薦下載IntelliJ IDEA來寫java

JNI的c/c++混合呼叫

  1. Main.java檔案

    package com.zero_waring.jni_test;
    
    public class Main {
        static {
            System.loadLibrary("hello"); //  libhello.so
        }
        private native void sayHello();
        public static void main(String[] args) {
    	// write your code here
            new Main().sayHello();
        }
    }
    
  2. 生成對應.h

    javah -classpath ~/IdeaProjects/JniTest/src com.zero_waring.jni_test.Main

    //在Main.java同級目錄下出現對應.h

  3. 編寫JNICppImpl.h檔案

    #ifndef _JNI_CPP_IMPL_
    #define _JNI_CPP_IMPL_
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void sayHello();
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    

    因為要被c呼叫所以使用extern c

  4. 編寫JNICppImpl.cpp檔案

    #include <iostream>
    #include "JNICppImpl.h"
    
    void sayHello() {
        std::cout << "this is jni" << std::endl;
    }
    
  5. 編譯要被java側呼叫的com_zero_waring_jni_test_Main.c

    #include <jni.h>
    #include "com_zero_waring_jni_test_Main.h"
    #include "JNICppImpl.h"
    
    JNIEXPORT void JNICALL Java_com_zero_1waring_jni_1test_Main_sayHello (JNIEnv *env, jobject thisObj) {
        sayHello();  // invoke C++ function
        return;
    }
    
  6. 編譯生成so

    g++ -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" -I ./ -shared com_zero_waring_jni_test_Main.c JNICppImpl.cpp  -o libhello.so
    
  7. 新增so 庫

    export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

    可以看到當前目錄下生成libhello.so

  8. 新增對應lib檔案到java路徑
    JVM的java.library.path屬性即為環境變數Path指定的目錄

    因為編譯我們依賴了IntelliJ IDEA,所以要新增對應動態庫路徑

    點選run,點選Edit Configurations

    選中Main

    然後在 VM opition中新增

    -Djava.library.path=/home/chao/IdeaProjects/JniTest/src/com/zero_waring/jni_test

    然後編譯就OK了