使用JNI将4字节wchar_t转换为String [英] 4-byte wchar_t to String conversion using JNI
问题描述
所以我有这个CanvasView,它显示了我的应用程序的调试信息.其基本覆盖的视图具有透明的背景,因此画布中绘制的所有内容都在屏幕中浮动.由于我需要返回wchar_t *的本机c ++的一些信息,由于android现在使wchar_t为4字节而jchar为2字节,我该如何使用env->NewString
?
so I have this CanvasView which shows debugging information of my app. Its basically overlayed view with transparant background so everything drawn in the canvas is floating in the screen. Since I need some information from native c++ which returns wchar_t*, how can I use env->NewString
since android now makes wchar_t is 4 bytes while jchar is 2 bytes?
我在我的lib中调用本机c ++函数的Java代码:
My java code that calls native c++ function in my lib:
private static String get_Name();
private class CanvasView extends View{
public CanvasView(Context context){
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paintText = new Paint();
paintText.setStyle(Paint.Style.FILL);
paintText.setColor(Color.WHITE);
paintText.setShadowLayer(5.5f, 0, 0, Color.BLACK);
paintText.setTextSize(convertSizeToDp(7.5f));
paintText.setTextAlign(Paint.Align.LEFT);
paintText.drawText(get_Name(), x, y, paintText);
// the rest of the code
// ...
}
}
get_Name
基本上返回一个来自NewString((const jchar* )myWchar, myLen)
get_Name
basically return a jstring which come from NewString((const jchar* )myWchar, myLen)
有时返回的结果是非unicode字符串,甚至在调用NewString
时我的应用程序也崩溃了.
The return results sometimes are non unicode string or even my app is crashing when NewString
is called.
推荐答案
首先,使用JNI分配ByteBuffer
:
First, allocate a ByteBuffer
using JNI:
wchar_t *input = ...;
jobject bb = env->NewDirectByteBuffer((void *) input, wcslen(input) * sizeof(wchar_t));
接下来,调用Charset.forName("UTF-32LE").decode(bb).toString()
:(每一段都是一个步骤)
Next, invoke Charset.forName("UTF-32LE").decode(bb).toString()
: (each paragraph is one step)
jclass cls_Charset = env->FindClass("java/nio/charset/Charset");
jmethodID mid_Charset_forName = env->GetStaticMethodID(cls_Charset, "forName", "(Ljava/lang/String;)Ljava/nio/charset/Charset;");
jobject charset = env->CallStaticObjectMethod(cls_Charset, mid_Charset_forName, env->NewStringUTF("UTF-32LE"));
jmethodID mid_Charset_decode = env->GetMethodID(cls_Charset, "decode", "(Ljava/nio/ByteBuffer;)Ljava/nio/CharBuffer;");
jobject cb = env->CallObjectMethod(charset, mid_Charset_decode, bb);
jclass cls_CharBuffer = env->FindClass("java/nio/CharBuffer");
jmethodID mid_CharBuffer_toString = env->GetMethodID(cls_CharBuffer, "toString", "()Ljava/lang/String;");
jstring ret = env->CallObjectMethod(cb, mid_CharBuffer_toString);
return ret;
注意:这取决于您所使用的平台的字节顺序.从此答案看来,所有的Android平台都是低端的.如果您使用的是Big-endian平台,则可能需要使用UTF-32BE
.
Note: this depends on the endianness of the platform you are on. From this answer it seems all Android platforms are little-endian. You may need to use UTF-32BE
instead if you are on a big-endian platform.
这篇关于使用JNI将4字节wchar_t转换为String的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!