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

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

背景之前已经介绍过JNI调用科大讯飞离线语音合成(Windows篇),今天我们接着聊一聊在Linux系统中如何使用科大讯飞离线语音合成,我们这里以(ubuntu)为例。
这里着重感谢以下博友的优秀文章,给了我很大帮助
Java web 项目中使用JNI技术(如何在运行时改变 java.library.path并生效
如何在运行时改变 java.library.path并生效
JNI错误之:error: base operand of ‘->’ has non-pointer type ‘_JNIEnv’
JNI中很有用的jstring 与 const char* 的相互转换函数
Linux C语言调用C++动态链接库-改

  1. 开始编码
    1.1 开始编写java代码
import java.lang.reflect.Field;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NativeKeDa {
    private static final Logger LOGGER = LoggerFactory.getLogger(NativeKeDa.class);

    public static void setLibraryPath(String path) throws Exception {
        System.setProperty("java.library.path", path);
        final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
        sysPathsField.setAccessible(true);
        sysPathsField.set(null, null);
    }

    static {
       // Linux系统中准备加载动态库(.so库)的位置
        String javaLibraryPath = "/kedaxunfei/lib/";
        try {
            setLibraryPath(javaLibraryPath);
            System.loadLibrary("kedaxunfei");
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            LOGGER.error("Native code library failed to load.\n" + e);
        }
    }

    public native int text2Speech(String content, String params, String filePath);

    public native void sayHello();
  }

1.2 生成.h 头文件

请参考
JNI调用科大讯飞离线语音合成(Windows篇)
https://blog.csdn.net/qq_34620527/article/details/89237601

1.3 编写 .cpp 文件,这里不能编写为 .c 文件,因为编写 .c 文件链接 libmsc.so 库时有问题

其他内容与 .c 文件相同
char * jstringToChar( JNIEnv * env, jstring jstr )
{
    char * rtn = NULL;
    jclass clsstring = env->FindClass("java/lang/String");
    jstring strencode = env->NewStringUTF("UTF-8");
    jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
    jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr,mid,strencode);
    jsize alen = env->GetArrayLength(barr);
    jbyte * ba = env->GetByteArrayElements(barr,JNI_FALSE);
    if(alen > 0)
    {
        rtn = (char*)malloc(alen+1); //new char[alen+1];
        memcpy(rtn,ba,alen);
        rtn[alen]=0;
    }
    env->ReleaseByteArrayElements(barr,ba,0);
    return rtn;
}

1.4 将.cpp 文件上传至Linux系统中,在.cpp文件目录中编译 .so 文件,这里需要使用 g++命令,命令如下:

g++ -fPIC -D_REENTRANT -shared -o libkedaxunfei.so kedaxunfei.cpp  -I "$JDKPath$/include" -I "$JDKPath$/include/linux"  -I "./" /**/**/**/libmsc.so  

注意:
libmsc.so 使用Linux中绝对路径
-I "./" 这里将科大讯飞 .h 文件和我们生成的 .h 文件放到一起了,因此这里也可以省略  

至此完成Linux JNI调用科大讯飞离线语音合成

欢迎大家留言技术交流
参考资料

Java web 项目中使用JNI技术(如何在运行时改变 java.library.path并生效)
https://www.imooc.com/article/14702

如何在运行时改变 java.library.path并生效
http://ju.outofmemory.cn/entry/150717

JNI错误之:error: base operand of ‘->’ has non-pointer type ‘_JNIEnv’
https://blog.csdn.net/fevershen/article/details/78645202

JNI中很有用的jstring 与 const char* 的相互转换函数
https://blog.csdn.net/liaowenfeng/article/details/8668085

Linux C语言调用C++动态链接库-改
https://blog.csdn.net/water_cow/article/details/45313339

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值