0

我有一页信息-字符串当内容在 JNI ( cpp dll ) 中时,我能够看到整个内容,但是当我们在 java 中看到相同的字符串时,最后一个单词被剪裁/截断。所以为了调试,我试图将JNI中的内容写入日志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->NewStringUTF(strFinal)"是否发生了截断 。1. 我可以将最后一行返回的内容写入日志文件吗?2. 为什么只有最后一个单词被截断(因为我已经测试了大小)?

有人可以帮助我吗?

4

1 回答 1

0

您的字符串数据可能会暴露字符串转换中的缺陷,这可以大大简化。

Java 字符串是 UTF-16 编码的 Unicode 字符的代码单元的计数序列。

ABSTR基本相同。(通常是这样。它最终取决于创建 BSTR 的代码。)

NewStringUTF接受以 0x00 结尾的经过修改的 UTF-8编码的 Unicode 字符的代码单元序列。如果这不是您传递的字符串的性质,那么它不是正确使用的函数。

我建议您使用NewString,将指针传递给BSTR字符及其长度。

处理字符串的一个很好的介绍是每个软件开发人员绝对、肯定必须了解 Unicode 和字符集的绝对最低要求——Joel Spolsky 的无借口。

更新:

你的 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);
}
于 2013-05-29T14:26:51.463 回答