0. 前言

最近工作的需要,需要讲SRILM通过JNI编译到Java程序中,一直没有找到一个完成的教程,遇到不少坑,特此整理,帮助大家少走弯路,不用各处去找,一篇文章解决问题。这里提供Mac和Linux两种系统的说明,请大家按照各自的系统进行。

1. SRILM的安装

SRILM的下载链接为http://www.speech.sri.com/projects/srilm/download.html 这里用的版本为1.7.1,创建安装的目录,假设安装目录为:$SRILM_HOME。
   在编译之前,需要修改一下的几个地方:
   1. 修改根目录的Makefile文件,添加一行SRILM = $SRILM_HOME,把SRILM在本地的位置写上。
   2. 同样在根目录的Makefile文件,找到MACHINE_TYPE := $(shell $(SRILM)/sbin/machine-type)这一行,如果是Mac电脑,那么将这个注释掉,加一行MACHINE_TYPE := macosx-m64(如果32位那就写32);如果是Linux,那么不需要注释,基本会自动识别的。
   3. 这个需要修改在common目录下的文件,如果是Mac系统,那么需要修改Makefile.machine.macosx,如果是Linux系统,需要根据你的系统情况找到对应的文件,查看系统情况使用uname -a命令。修改的内容均一样,找到GCC_FLAGS = -Wall -Wno-unused-variable -Wno-uninitialized -Wno-overloaded-virtual这一行,修改为GCC_FLAGS = -Wall -Wno-unused-variable -Wno-uninitialized -Wno-overloaded-virtual -fPIC。这一步很关键,否则会有错。具体解释参见http://blog.csdn.net/u010312436/article/details/52486811。
修改之后,就可以在srilm的目录中输入make World进行编译,编译结束之后,输入make test检查,如果大部分结果都为IDENTITY,那么证明编译成功。

2. 利用JNI生成头文件

这一步就是正常JNI的步骤,首先编写一个类来描述需要写的接口,例子如下
public class LMCaculate {
    // TAG for log.private static final String TAG = "LMCaculate";// Single Instance.private static LMCaculate instance = null;// Get instance.public static LMCaculate getInstance() {if(instance == null) {instance = new LMCaculate();System.load(Config.LM_jni);instance.init(Config.LM_file, 3);}return instance;}public native boolean init(String modelPath, int ngramOrder);public native void release();public native float calcProbSequence(String wordsSequence, String context);
}

需要接口完成的函数需要添加native标签,这里主要利用三个方法,一个是将lm文件读入内存,另一个是将释放资源,最后是计算语言模型的概率。

随后利用javah命令生成头文件,利用srilm编写对应的cpp文件。

3. 编写makefile文件

得到这两部分内容之后,接下来就是编译的步骤,这里直接将Mac平台和Linux平台的makefile贴出来,大家可以根据自己的情况进行修正。首先是Linux的makefile文件
Srilm_INCLUDE = $SRILM_HOME/include \
-I /usr/lib/jvm/java-7-openjdk-amd64/includeSrilm_LIB = $SRILM_HOME/lib/i686-m64/liboolm.a \$SRILM_HOME/lib/i686-m64/libmisc.a \$SRILM_HOME/lib/i686-m64/liblattice.a \$SRILM_HOME/lib/i686-m64/libflm.a \$SRILM_HOME/lib/i686-m64/libdstruct.a \$SRILM_HOME/lib/i686-m64/libz.alibCalcSentProb.so: jni.o $(Srilm_LIB)g++ -shared -o libCalcSentProb.so jni.o $(Srilm_LIB)  -lpthread -fopenmp
jni.o: jni.cppg++ -fPIC -I $(Srilm_INCLUDE) -c jni.cpp -o jni.o

这里的jni.cpp就是上一步根据jni生成的头文件写的cpp文件
在Mac上的Makefile文件为
Srilm_INCLUDE = $SRILM_HOME/include \-I /Library/Java/JavaVirtualMachines/jdk1.8.0_66.jdk/Contents/Home/include \-I /Library/Java/JavaVirtualMachines/jdk1.8.0_66.jdk/Contents/Home/include/darwin/Srilm_LIB = $SRILM_HOME/lib/macosx-m64/liboolm.a \$SRILM_HOME/lib/macosx-m64/libmisc.a \$SRILM_HOME/lib/macosx-m64/liblattice.a \$SRILM_HOME/lib/macosx-m64/libflm.a \$SRILM_HOME/lib/macosx-m64/libdstruct.a \$SRILM_HOME/lib/macosx-m64/libz.alibCalcSentProb.dylib: jni.o $(Srilm_LIB) libiconv.dylibg++ -shared -o libCalcSentProb.dylib jni.o $(Srilm_LIB) libiconv.dylib
jni.o: jni.cppg++ -fPIC -I $(Srilm_INCLUDE) -c jni.cpp -o jni.o

这里需要说明的是,在Mac中虽然有libiconv.dylib,但是在g++编译的过程中不会自动加入,需要手动从/usr/lib目录中拷贝出来(记得是拷贝,不是剪切!),放在本地目录即可。

通过这种方式就可以获得SRILM的java接口
   

SRILM的java接口相关推荐

  1. Java接口对Hadoop集群的操作

    Java接口对Hadoop集群的操作 首先要有一个配置好的Hadoop集群 这里是我在SSM框架搭建的项目的测试类中实现的 一.windows下配置环境变量 下载文件并解压到C盘或者其他目录. 链接: ...

  2. 推荐一个 Java 接口快速开发框架

    欢迎关注方志朋的博客,回复"666"获面试宝典 今天给小伙伴们介绍一个Java接口快速开发框架-magic-api 简介 magic-api 是一个基于 Java 的接口快速开发框 ...

  3. java接口如何定义常量 c_在Java接口中怎样访问定义的常量呢?

    java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能).那么我们在Java接口中怎 ...

  4. Java接口和Java抽象类

    Java接口和Java抽象类有太多相似的地方,又有太多特别的地方,究竟在什么地方,才是它们的最佳位置呢?把它们比较一下,你就可以发现了. 1.Java接口和Java抽象类最大的一个区别,就在于Java ...

  5. java接口深入理解,深入理解Java接口

    从java接口是什么到为什么,理解java接口,主要解决三个问题 1.java接口是什么 2.java接口为什么 3.java接口怎么用 java接口是什么 接口是方法的抽象,通过接口规定类需要实现那 ...

  6. java安全接口调用_步骤3:调用Java接口

    本文档主要介绍了通过调用Java接口生成工作密钥和进行通用数据加解密的操作方法. 整体流程 初始化SDK.具体内容请参见 配置Java接口.具体内容请参见 初始化SDK 使用以下方法初始化SDK.hs ...

  7. 对接第三方平台JAVA接口问题推送和解决

    对接第三方平台JAVA接口问题推送和解决 参考文章: (1)对接第三方平台JAVA接口问题推送和解决 (2)https://www.cnblogs.com/CreateMyself/p/7295879 ...

  8. java 接口与抽象类的区别

    1.概述 一个软件设计的好坏,我想很大程度上取决于它的整体架构,而这个整体架构其实就是你对整个宏观商业业务的抽象框架,当代表业务逻辑的高层抽象层结构 合理时,你底层的具体实现需要考虑的就仅仅是一些算法 ...

  9. Java接口interface

    Java接口interface 1.多个无关的类可以实现同一个接口. 2.一个类可以实现多个无关的接口. 3.与继承关系类似,接口与实现类之间存在多态性. 接口(interface)是抽象方法和常量值 ...

最新文章

  1. python基础语言与应用第五章_《Python基础教程》 读书笔记 第五章(下)循环语句...
  2. Oracle调用接口(OCI)源码剖析(2):执行SQL语句并获取结果
  3. C语言socket getsockopt() setsockopt()函数(获取和设置套接口的选项?)
  4. 银角大王 python_小猿圈python学习-细讲数据类型-列表
  5. 设计模式——工厂模式(一)
  6. C++ STL : 模拟实现STL中的容器适配器priority_queue
  7. visio的字体复制到word_学会这6个常用Word技巧,文档做起来又快又好看,办公如有神助...
  8. java seconds_Java LocalTime minusSeconds()用法及代码示例
  9. 计算机学科技术前沿:互联网上信息可信性的现状
  10. windows server2012在已有.net4.5框架的基础上安装.net3.5的方法
  11. html5音乐播放器格式midi,HTML5 Audio时代的MIDI音乐文件播放
  12. 国际科学数据服务平台 - csdb_拔剑-浆糊的传说_新浪博客
  13. 中兴新支点操作系统_中兴新支点操作系统下载
  14. 阿尔伯塔计算机硕士要求,阿尔伯塔大学计算机硕士专业介绍
  15. c语言输出0.000000或乱码,深究
  16. 主码流和辅码流的区别
  17. 8-25 26 veriloga语言
  18. proe常用c语言语句,Proe如何使用if条件语句?
  19. c语言作业报告,C语言程序设计综合作业报告——作业管理系统
  20. python一键批量制作word邀请函

热门文章

  1. iText7高级教程之构建基础块——1.引入字体
  2. python中对GIL的理解
  3. 那些开源协议可以商用
  4. 干货!11个产品营销策略(一)
  5. 神策数据新 DEMO 上线,助力零售行业数据分析
  6. 解决vc2017不能建立对话框类的问题
  7. ❤️手把手教你配置服务器板载raid❤️
  8. CentOS7编译WD My Cloud下的SVN(Subversion)(附编译好的SVN的链接)
  9. 关于Freesurfer提取annotation分区结构特征的命令mri_segstats
  10. EF6 使用 和 连接MySql 数据库-闪退和若干问题解决