2

I'm trying to pass a java.lang.String from Java to C++ but there seems to be a little mistake in the code encoding from java String to Windows WCHAR*.

On the Java side I have

public native void sendText(String text);

And on the C++ side

JNIEXPORT void JNICALL Java_test_sendText(JNIEnv *env, jobject o, jstring text) {
    const jchar* _text = env->GetStringChars(text, FALSE);

    const WCHAR* txt = (const WCHAR*)_text;
    UINT32 len = (UINT32)wcslen(txt);
    IDWriteTextLayout* textLayout;
    DWriteFactory->CreateTextLayout(txt, len, textFormat, rect.right - x, rect.bottom - y, &textLayout);

    g->DrawTextLayout(D2D1::Point2F(x, y), textLayout, currBrush);
    env->ReleaseStringChars(text, _text);
}

I'm trying to send the String test string: 00:00:00 but on the C++ side I'm getting things like Àest string: 00:00:00 and Ùest string: 00:00:00. It seems like only the first character is failing to convert, I have the unicode charset selected in MSVS but I don't have a clue what's going wrong. I have searched around and other posts say a simple cast between jchar* and wchar_t* should be possible.

manuell
  • 7,528
  • 5
  • 31
  • 58
MircoProgram
  • 295
  • 1
  • 20
  • 1
    The second parameter to `GetStringChars` is a pointer; `nullptr` might be clearer than `FALSE`. (Although both are valid.) – Alan Stokes Apr 16 '16 at 12:51
  • How are you finding the value of the string on the C++ side? If you're printing it, how? – Alan Stokes Apr 16 '16 at 12:51
  • Well the reason I'm casting to WCHAR* is because I use the string to draw text on the screen using DirectWrite. `UINT32 len = (UINT32)wcslen(txt); IDWriteTextLayout* textLayout; DWriteFactory->CreateTextLayout(txt, len, textFormat, rect.right - x, rect.bottom - y, &textLayout);` – MircoProgram Apr 16 '16 at 12:59
  • Try something simpler (eg call `MessageBoxW`) to verify the string. Or show some more code. – Alan Stokes Apr 16 '16 at 13:00
  • I added some more code – MircoProgram Apr 16 '16 at 13:03
  • 1
    You should use `env->GetStringLength(text)` to get the length, rather than `wcslen` (the Java string may not be zero terminated). But I doubt that's your problem. – Alan Stokes Apr 16 '16 at 13:10
  • Possible duplicate of [How do I convert jstring to wchar\_t \*](http://stackoverflow.com/questions/68042/how-do-i-convert-jstring-to-wchar-t) – Andrew Henle Apr 16 '16 at 13:59
  • In theory, jchar and WCHAR are not the same (see http://stackoverflow.com/a/7881134/192373). For some use cases the distinction is critical, but it does not explain the observed behavior – Alex Cohn Apr 16 '16 at 17:56
  • Do you see the first character incorrect in debugger? – Alex Cohn Apr 16 '16 at 17:59
  • when I try `MessageBox(..)` or `MessageBoxW(..)` the box doesn't show, but when I do `const WCHAR* _text = L"Test string here"; UINT32 len = (UINT32)wcslen(_text); DWriteFactory->CreateTextLayout(_text, len, textFormat, rect.right - x, rect.bottom - y, &textLayout);` the string shows up fine. – MircoProgram Apr 21 '16 at 18:08
  • @AndrewHenle: When I try the solution you linked it still shows the first character bugged. – MircoProgram Apr 21 '16 at 18:20

0 Answers0