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文件

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