最后一个单词在jni中被剪切/截断

时间:2013-05-29 07:11:52

标签: java c++ java-native-interface jnienv

我有一页信息 - 字符串 当内容在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.为什么只有最后一个单词被截断(因为我测试了大小)?

有人可以帮帮我。

1 个答案:

答案 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);
}