jni中多個cpp類的使用

測試環境描述

以下內容所使用環境ubuntu、jdk1.8

本文文件描述

Test.java

主要完成的功能是使用生成jni對應的Test.h,新建Test.cpp寫入內容,再去生成libTest.so,然後在Java類中加載

fingerprintExtract.cpp

c++的一些功能類,爲了方便在Test.cpp中被使用,把該文件編譯成對應的.so庫

fftw

在fingerprintExtract.cpp被使用,一個開源庫,.configure、make的時候會生成.so庫

jni的描述

JNI是Java Native Interface的縮寫,通過使用 Java本地接口書寫程序,可以確保代碼在不同的平臺上方便移植

編譯在後面使用到的fftw庫

./configure --prefix=/home/zy/test/zengraoli_jni_plus/fftw-3.3.8/output --enable-shared
make -j32
make install

在這裏插入圖片描述
修改庫的搜索路徑,或者把libfftw3.so.3拷貝到/usr/local/lib中,並重命名爲libfftw3.so

修改庫路徑的兩種方法

第一種方法,修改庫路徑

sudo vim /etc/ld.so.conf

在最後一行插入

/home/zy/test/zengraoli_jni_plus/fftw-3.3.8/output/lib

編輯完成之後使用

sudo ldconfig

更新一下

第二種方法,拷貝到/usr/local/lib

sudo cp libfftw3.so.3 /usr/local/lib/libfftw3.so

生成Java調用的入口點

寫對應的Java文件Test.java

public class Test
{
    static
    {
        System.load("/home/zy/test/zengraoli_jni_plus/libTest.so"); //libmain.so是jni要生成的so文件
    }
    public native void extractFingerPrint(String inputVoices, String  dataHash); // 聲明jni導出的函數 //聲明的add()函數,在後面他封裝了類Twono中的Add()函數
    public static void  main(String[] args)
    {
        String inputVoices = "/home/zy/migudata/source/";
        String dataHash = "/home/zy/fingerPrint/fingerprint/data/hash709.txt";
        Test main = new Test();
        main.extractFingerPrint(inputVoices,dataHash); // 調用jni導出的函數extractFingerPrint
    }
}

用Java文件生成jni對應頭文件Test.h

javac Test.java
javah Test

補充Test.cpp文件

寫入以下內容

#include "stdio.h"
#include "Test.h"

#include <fstream>
#include <string>
#include <time.h>
#include "fingerprintExtract.h"


using namespace std;

JNIEXPORT void JNICALL Java_Test_extractFingerPrint
  (JNIEnv *env, jobject obj, jstring inputVoices, jstring dataHash)
{
printf("zengraoli begin.\r\n");

const char *input = env->GetStringUTFChars(inputVoices, NULL);
        string inputPath = input;
        env->ReleaseStringUTFChars(inputVoices, input);

        const char *data = env->GetStringUTFChars(dataHash, NULL);
        string dataPath = data;
        env->ReleaseStringUTFChars(dataHash, data);

        fingerprintExtract fingerprintTemp;
        fingerprintTemp.fingerprintVoices(inputPath , dataPath);

printf("zengraoli end.\r\n");

}

fingerprintExtract.h的內容如下

#pragma once
#include "hash.h"
#include "fingerprint.h"
#include "FileChange.h"
#include "time.h"
#include <dirent.h>
//#include <Windows.h>
//#include <io.h>
class fingerprintExtract {
private:
public:
    void fingerprintVoices(string inputVoices, string dataHash);
    void ProcessVoices(const char *voicesPath);
};

fingerprintExtract.cpp主要涉及到一些業務操作,依賴fftw這個庫,所以代碼可以任意

在linux上面編譯生成fingerprintExtract.so

fingerprintExtract.cpp在生成的.so的時候,依賴了hash、fingerprint、FileChange,這幾個文件需要在生成時候一塊編譯

g++ -fPIC -shared  -o libfingerprintExtract.so FileChange.cpp wav.cpp hash.cpp fingerprint.cpp fingerprintExtract.cpp

ldd -r libfingerprintExtract.so

查看一下.so,發現這個時候是沒有引入fftw.a造成函數找不到的問題
在這裏插入圖片描述
但其他的函數都正確了

那麼只需要在生成Test.so的時候把這個.a庫鏈接進來即可

生成jni對應的so文件

g++ -fPIC -I/home/wfx/usr/java/jdk1.8.0_111/include -I/home/wfx/usr/java/jdk1.8.0_111/include/linux -I/home/zy/test/zengraoli_jni_plus/fftw-3.3.8/output/include -L/home/zy/test/zengraoli_jni_plus/fftw-3.3.8/output/lib -L. -shared -o libTest.so -lfftw3 -lfingerprintExtract Test.cpp

查看libTest是否有函數找不到鏈接

ldd -r libTest.so

在這裏插入圖片描述

執行Java文件中的main查看對應的函數是否被調用

可以看到,調用已經沒有問題了
在這裏插入圖片描述

判斷.so文件是否爲debug版本

readelf -S libTest.so

如果沒有看到有debug字段,那麼則直接就是release對應的.so文件

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