文章目錄
測試環境描述
以下內容所使用環境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文件