最近项目要求需要重新写一个kaldi的新模块,并且要用java去调用kaldi的这个模块。因为之前没有接触过JNI以及对kaldi底层配置,编译原理不熟悉,导致自己吃了很多碰,浪费了好多时间,再外加上kaldi这块的资料是真的不太多,因此自己写一个博客,一方面作为备忘录,另一方面希望以后能帮到有些kaldi的学习和使用者。

这个过程中有两篇博客对我帮助很大,在这对这两位表示感谢,帮了很大的忙:

[1]https://blog.csdn.net/hongquan1991/article/details/12426615

这位作者对linux/Ubuntu 下使用 java 调用 so 动态链接库步骤讲很好,我也是从这去了解如何去调用so文件的

[2] https://github.com/ahmetaa/kaldi-jni

这个项目的Makefile文件写的很好。我也主要借鉴了他的makefile文件

接下来步入正题:

因为java的jni要调用c++的函数的话,需要调用cpp的动态链接库(so文件)而不是静态链接库(o文件),但是kaldi默认是生成静态链接库,所以我们最需要重新编译kaldi,让他能生成动态链接库

第一步:在kaldi/src目录下make clean(清楚之前编译文件)

第二步:打开kaldi/src目录下run_config.sh文件,文件如下


# Kaldi compiled with static, cuda and openblas.
# For further dynamic linking based on kaldi (usually no cuda),
# compile openfst and kaldi with -fPIC by modifying
# ../tools/Makefile and kaldi.mk with "CXXFLAGS += -fPIC".
# kaldi.mk is generated by running ./configure below.
./configure --static \--use-cuda=yes --cudatk-dir=/usr/local/cuda-9.0 \--mathlib=ATLAS --atlas-root=../tools/ATLAS_headers/\--threaded-math=no --static-math=yes \--static-fst=yes --fst-root=../tools/openfst

将"--static" 改为"--shared" ,保存并退出。

第三步:打开kaldi/tools目录下Makefile文件,在文件第五行处加上

CXXFLAGS += -fPIC

保存并退出。

第四步:打开kaldi/src目录下Makefile文件,在SUBDIRS 变量下,加入你自己新模块的目录(我的是叫testbin)

SUBDIRS = base matrix util feat cudafeat tree gmm transform \fstext hmm lm decoder lat kws cudamatrix nnet \bin fstbin gmmbin fgmmbin featbin cudafeatbin \nnetbin latbin sgmm2 sgmm2bin nnet2 nnet3 rnnlm chain nnet3bin nnet2bin kwsbin \ivector ivectorbin online2 online2bin lmbin chainbin rnnlmbin \cudadecoder cudadecoderbin  testbin

并在添加依赖项

### Dependency list ###
# this is necessary for correct parallel compilation
#1)The tools depend on all the libraries
bin fstbin gmmbin fgmmbin sgmm2bin featbin cudafeatbin nnetbin nnet2bin nnet3bin chainbin latbin ivectorbin lmbin kwsbin online2bin rnnlmbin testbin cudadecoderbin: \base matrix util feat cudafeat tree gmm transform sgmm2 fstext hmm \lm decoder lat cudamatrix nnet nnet2 nnet3 ivector chain kws online2 rnnlm \cudadecoder

第五步编译kaldi,你会发现这次的kaldi比之前在src下多了几文件夹,打开src下lib文件夹你就会发现你生成的so在这里:

libhh.so@                         --> /data/kaldi-caser/src/testbin/libhh.so
libkaldi-base.so@                 --> /data/kaldi-caser/src/base/libkaldi-base.so
libkaldi-chain.so@                --> /data/kaldi-caser/src/chain/libkaldi-chain.so
libkaldi-cudadecoder.so@          --> /data/kaldi-caser/src/cudadecoder/libkaldi-cudadecoder.so
libkaldi-cudafeat.so@             --> /data/kaldi-caser/src/cudafeat/libkaldi-cudafeat.so
libkaldi-cudamatrix.so@           --> /data/kaldi-caser/src/cudamatrix/libkaldi-cudamatrix.so
libkaldi-decoder.so@              --> /data/kaldi-caser/src/decoder/libkaldi-decoder.so
libkaldi-feat.so@                 --> /data/kaldi-caser/src/feat/libkaldi-feat.so
libkaldi-fstext.so@               --> /data/kaldi-caser/src/fstext/libkaldi-fstext.so
libkaldi-gmm.so@                  --> /data/kaldi-caser/src/gmm/libkaldi-gmm.so
libkaldi-hmm.so@                  --> /data/kaldi-caser/src/hmm/libkaldi-hmm.so
libkaldi-ivector.so@              --> /data/kaldi-caser/src/ivector/libkaldi-ivector.so
libkaldi-kws.so@                  --> /data/kaldi-caser/src/kws/libkaldi-kws.so
libkaldi-lat.so@                  --> /data/kaldi-caser/src/lat/libkaldi-lat.so
libkaldi-lm.so@                   --> /data/kaldi-caser/src/lm/libkaldi-lm.so
libkaldi-matrix.so@               --> /data/kaldi-caser/src/matrix/libkaldi-matrix.so
libkaldi-nnet.so@                 --> /data/kaldi-caser/src/nnet/libkaldi-nnet.so
libkaldi-nnet2.so@                --> /data/kaldi-caser/src/nnet2/libkaldi-nnet2.so
libkaldi-nnet3.so@                --> /data/kaldi-caser/src/nnet3/libkaldi-nnet3.so
libkaldi-online2.so@              --> /data/kaldi-caser/src/online2/libkaldi-online2.so
libkaldi-rnnlm.so@                --> /data/kaldi-caser/src/rnnlm/libkaldi-rnnlm.so
libkaldi-sgmm2.so@                --> /data/kaldi-caser/src/sgmm2/libkaldi-sgmm2.so
libkaldi-transform.so@            --> /data/kaldi-caser/src/transform/libkaldi-transform.so
libkaldi-tree.so@                 --> /data/kaldi-caser/src/tree/libkaldi-tree.so
libkaldi-util.so@                 --> /data/kaldi-caser/src/util/libkaldi-util.so

testbin下的makefile文件,仿照链接2所写,其中加了一些我自己模块所以来的kaldi库,跟链接2大差不差,我也贴出来了

all:
EXTRA_CXXFLAGS = -Wno-sign-compare
include ../kaldi.mkLDFLAGS += $(CUDA_LDFLAGS)
LDLIBS += $(CUDA_LDLIBS)JNI_HEADERS_1 = /data/java/jdk-13.0.1/includeJNI_HEADERS_2 = /data/java/jdk-13.0.1/include/linuxcuda-compiled.o: ../kaldi.mkOBJFILES = hh.oLIBNAME = hhTESTFILES =ADDLIBS = ../hmm/kaldi-hmm.a ../feat/kaldi-feat.a \../transform/kaldi-transform.a ../gmm/kaldi-gmm.a \../tree/kaldi-tree.a ../util/kaldi-util.a ../matrix/kaldi-matrix.a \../base/kaldi-base.a ../nnet3/kaldi-nnet3.a ../chain/kaldi-chain.a \../cudamatrix/kaldi-cudamatrix.a ../decoder/kaldi-decoder.a \../lat/kaldi-lat.a ../fstext/kaldi-fstext.aCXXFLAGS += -I$(JNI_HEADERS_1)CXXFLAGS += -I$(JNI_HEADERS_2)include ../makefiles/default_rules.mk
~
~
~

其中libhh.so为我的新模块的so文件,至此大功告成!

至于JNI怎么调用,以及cpp文件应该怎么写,请看链接一 写的很好,肯定能看懂!

Java JNI调用kaldi动态链接库(Linux版本)相关推荐

  1. Java通过JNI调用C++动态链接库dll,并打在jar包内 ——JNA-JNI(一)

    Java通过JNI调用C++动态链接库dll,并打在jar包内--JNA-JNI(一) 系列文章: Java通过JNI调用C++动态链接库dll,并打在jar包内 --JNA-JNI(一) Java使 ...

  2. JAVA通过JNI调用C++动态链接库CLL(二)

    简介 使用Visual Studio 2017新建c++动态链接库dll项目 编写JniDemo.h中getName实现并生成DLL 编写JniDemo.h在JniDemo.c实现getName方法 ...

  3. JAVA通过JNI调用C++动态链接库CLL(一)

    简介 使用eclipse新建JAVA项目并生成.h头文件 新建项目JniDemo 新建测试类JniTest并声明一个native的方法 使用Javah命令生成native方法的声明的C/C++头文件 ...

  4. Java JNI调用IC卡读卡器

    Java JNI调用IC卡读卡器 Java调用IC卡读卡器的DLL一般有以下2种方式: 1.使用JNative第三方库调用IC卡读卡器dll的接口. 2.使用JNI调用IC卡读卡器dll的接口. JN ...

  5. java JNI调用C语言动态链接库(java.lang.UnsatisfiedLinkError: no yourClassName in java.library.path 异常的解决方法)

    转自: http://watershitter.iteye.com/blog/477615 今天花了至少3个小时跑这个java调c的动态链接库的Hello,native world的程序.  把所有犯 ...

  6. JAVA JNI调用科大讯飞离线语音合成(Linux篇)

    JNI调用科大讯飞离线语音合成(Linux篇) 背景:之前已经介绍过JNI调用科大讯飞离线语音合成(Windows篇),今天我们接着聊一聊在Linux系统中如何使用科大讯飞离线语音合成,我们这里以(u ...

  7. java jni调用dll文件_Java通过jni调用动态链接库

    (1)JNI简介 JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++).从Java1.1开始,JNI标准成为java ...

  8. java linux 调用so文件,linux下java jni调用.so文件的方法

    刚刚试过一个这样的例子,省事起见,略改并记录如下: //package net.wangliping; 2 public class Hello 3 { 4     static 5     { 6 ...

  9. java jni调用dll_浅谈JNI的使用--java调用dll(原创)

    什么是JNI?Java Native Interface(Java本地接口)的简写.使用这个接口,可以轻松实现java对动态链接库Dynamic Link Library(dll)文件的调用,以实现一 ...

  10. Java JNI调用C语言中的函数

    1.调用无参函数 java code public class JNITest {static {/*加载*/System.loadLibrary("mynative");}pub ...

最新文章

  1. mysql function使用
  2. 【UWB】ELM,Extreme Learning Machine 极限学习机
  3. 结对开发——求最大值
  4. PostgrSQL流复制wal异常
  5. 基于maven创建一个javaweb项目
  6. 进入路由器boot的方式
  7. 最大子数列和的问题求解
  8. python批量保存网页为pdf_在chrome中自动打印/保存网页为pdf - python 3.6
  9. Js实现背景图片切换
  10. 21届校招中获得12家公司offer的一些经验(包括6家银行信息科技岗offer)
  11. 2021前端智能化发展现状与未来展望
  12. 华为手机浏览器 onclick失灵的问题
  13. 计算机网络连接黄感叹号,电脑连接路由器网络连接显示黄色感叹号的解决办法...
  14. Kyligence Zen 产品体验 — “人人都是数据分析师”
  15. RK3566触屏旋转方向
  16. linux nginx安装https安全证书
  17. 盘古开源解析:物联网时代的芯片产业新趋势
  18. @Configuration注解 -【Spring底层原理】
  19. PHPstudy小白起步
  20. 求第 N 个 斐波那契数的多种方法

热门文章

  1. http接口 Spring boot中的Http压缩配置gzip
  2. 甘超波:NLP如何挖掘信念
  3. APK一键注入网络验证后台PHP源码ThinkPHP开发版
  4. SQL SERVER/ROW_NUMBER() OVER (ORDER BY id)高效分页
  5. 关于主机名,域名区别(www.baidu.com与baidu.com)以及同源策略的一些误区
  6. 冰点还原8.53破解版
  7. Android应用内加载pdf 使用pdf.js
  8. 向Docker告别的时候到了
  9. C语言回文数判断,结果写入文件中
  10. 2022年中国大学排行榜出炉~