最近刚开始接触java编程然后需要做一个语音合成,现在的情况是我使用C++直接调用SAPI后打包成DLL再去Java中调用,但是发现在C++中可以正常使用的Speak函数在Java中会读出乱码并且每次读的都不一样,初步怀疑是在C++中Speak函数的形参是LPSWSTR/LPCTSTR的宽字符型,而我Java中传入的参数是JAVA中的String型,不知道是不是这个问题,有什么解决方案吗,或者老哥们有什么想法?
C++的dll那里,include jni.h,返回值定义成jstring,
用这个转换
jstring charTojstring(JNIEnv* env, const char* str) {
jstring rtn = 0;
int slen = strlen(str);
unsigned short * buffer = 0;
if (slen == 0)
rtn = (env)->NewStringUTF(str);
else {
int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR) str, slen, NULL, 0);
buffer = (unsigned short *) malloc(length * 2 + 1);
if (MultiByteToWideChar( CP_ACP, 0, (LPCSTR) str, slen, (LPWSTR) buffer, length) > 0)
rtn = (env)->NewString((jchar*) buffer, length);
// 释放内存
free(buffer);
}
return rtn;
}
https://blog.csdn.net/xlxxcc/article/details/51106721
老兄,一般宽窄字符需要有个转换的,c++里面是MultiByteToWideChar,不知你java里面有没有类似函数,转一下再传过去呗
//把宽字符串转换成字符串,输出使用
string wstring2string(wstring sToMatch)
{
#ifdef _A_WIN
string sResult;
int iLen = WideCharToMultiByte( CP_ACP, NULL, sToMatch.c_str(), -1, NULL, 0, NULL, FALSE ); // 计算转换后字符串的长度。(包含字符串结束符)
char *lpsz = new char[iLen];
WideCharToMultiByte( CP_OEMCP, NULL, sToMatch.c_str(), -1, lpsz, iLen, NULL, FALSE); // 正式转换。
sResult.assign( lpsz, iLen - 1 ); // 对string对象进行赋值。
delete []lpsz;
#elif _A_LINUX
int iLen = wcstombs( NULL, sToMatch.c_str(), 0 ); // 计算转换后字符串的长度。(不包含字符串结束符)
char *lpsz = new char[iLen + 1];
int i = wcstombs( lpsz, sToMatch.c_str(), iLen ); // 转换。(没有结束符)
lpsz[iLen] = '/0';
string sResult(lpsz);
delete []lpsz;
#endif
return sResult;
}
直接都搞成字节来处理吧