我有一页信息 - 字符串 当内容在JNI( cpp dll )中时,我能够看到整个内容,但是当我们在java中看到相同的字符串时,最后一个字被剪切/截断。所以为了调试,我试图将JNI中的内容写入log txt文件。
JNIEXPORT jstring JNICALL Java_com_native_ExeCOM_GetResultDetails
(JNIEnv *env, jclass obj)
{
_bstr_t bstrIntermediate( execution->GetResultDetails());
//WriteContentToLog((LPCTSTR)bstrIntermediate); //Able to write this to log (no loss)
CString strFinal;
strFinal.Format(_T("%s"), (LPCTSTR)bstrIntermediate);
//WriteContentToLog((LPCTSTR)strFinal); //Able to write this to log (no loss)
return env->NewStringUTF(strFinal);
}
using namespace std;
#define FILE "C:\\Temp\\debug.txt"
ofstream DEBUG_STRM;
void WriteContentToLog(const std::string &msg){
DEBUG_STRM.open (FILE,fstream::app);
DEBUG_STRM <<msg<<"\n"; DEBUG_STRM.close();
}
返回jstring后,如果我们从java端分析相同的内容,那么内容中的最后一个单词将被剪切/截断。
我想看看是否在最后一行“env-&gt; NewStringUTF(strFinal)”中发生了截断。 1.我可以将最后一行返回的内容写入日志文件吗? 2.为什么只有最后一个单词被截断(因为我测试了大小)?
有人可以帮帮我。
答案 0 :(得分:0)
你的字符串数据可能会暴露你的字符串转换中的缺陷,这可能会大大简化。
Java字符串是UTF-16编码的Unicode字符的代码单元的计数序列。
BSTR
基本相同。 (通常就是这样。它最终取决于创建BSTR的代码。)
NewStringUTF
接受以modified UTF-8编码的Unicode字符为代码单元的0x00终止序列。如果这不是你传递的字符串的性质,那么它就不适合使用。
我建议您使用NewString
,并将指针传递给BSTR
字符及其长度。
Joel Spolsky The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets—No Excuses对琴弦的处理有一个很好的介绍。
更新:
您的JNI功能可以写成:
JNIEXPORT jstring JNICALL Java_com_native_ExeCOM_GetResultDetails
(JNIEnv *env, jclass obj)
{
BSTR bstr = execution->GetResultDetails();
jstring str = env->NewString(bstr, SysStringLen(bstr));
SysFreeString(bstr); // assuming GetResultDetails transfers ownership
return str;
}
要找出BSTR实际包含的内容,请使用此函数转储它。注意:字节打印为ASCII字符仅用于方向。上面的实现假定它是典型的BSTR,即它包含UTF-16编码的Unicode字符。
void DumpBstr( BSTR bstr )
{
unsigned char *buffer = (unsigned char *)bstr;
unsigned int *length = (((unsigned int *)bstr) - 1);
unsigned short *terminator =(unsigned short *)(buffer + *length);
UINT len = SysStringLen(bstr);
UINT byteLen = SysStringByteLen(bstr);
printf("Dumping BSTR at %p\n", bstr);
printf(" %s\n", (char *)bstr);
printf(" SysStringLen %i\n", len); // A BSTR created with SysAllocStringByteLen can have an odd byte length. SysStringLen presumes an even number of bytes.
printf(" SysStringByteLen %i\n", byteLen);
if (bstr==NULL) { printf(" NULL is equivalent to an empty string. [VB can pass a BSTR this way and SysStringLen et al account for this]"); return;}
printf(" Hidden length field %i\n", *length);
{
unsigned int i;
for (i = 0; i < *length; i++)
{
printf(" Byte %02X %c\n", *(buffer + i), *(buffer + i));
}
}
printf(" Hidden terminator field %04X\n", *terminator);
}