How do I convert jstring to wchar_t *
假设在C ++方面,我的函数采用名为myString的类型jstring的变量。 我可以将其转换为ANSI字符串,如下所示:
1
| const char* ansiString = env->GetStringUTFChars(myString, 0); |
有没有办法
const wchar_t* unicodeString = ...
如果这对某人有帮助...我已将此功能用于Android项目:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| std::wstring Java_To_WStr(JNIEnv *env, jstring string)
{
std::wstring value;
const jchar *raw = env->GetStringChars(string, 0);
jsize len = env->GetStringLength(string);
const jchar *temp = raw;
while (len > 0)
{
value += *(temp++);
len--;
}
env->ReleaseStringChars(string, raw);
return value;
} |
一个改进的解决方案可能是(感谢您的反馈):
1 2 3 4 5 6 7 8 9 10 11 12 13
| std::wstring Java_To_WStr(JNIEnv *env, jstring string)
{
std::wstring value;
const jchar *raw = env->GetStringChars(string, 0);
jsize len = env->GetStringLength(string);
value.assign(raw, raw + len);
env->ReleaseStringChars(string, raw);
return value;
} |
谁释放了wsz?
我会推荐STL!
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| std::wstring JavaToWSZ(JNIEnv* env, jstring string)
{
std::wstring value;
if (string == NULL) {
return value; // empty string
}
const jchar* raw = env->GetStringChars(string, NULL);
if (raw != NULL) {
jsize len = env->GetStringLength(string);
value.assign(raw, len);
env->ReleaseStringChars(string, raw);
}
return value;
} |
JNI也具有GetStringChars()函数。返回类型为const jchar *,在Win32上jchar为16位,因此与wchar_t兼容。不知道这是真正的UTF-16还是其他东西...
一个可移植且强大的解决方案是使用iconv,但要了解您必须知道系统wchar_t使用的编码方式(例如,在Windows上为UTF-16,在许多Unix系统上为UTF-32)。
如果要最大程度地减少对第三方代码的依赖性,还可以手动滚动自己的UTF-8转换器。如果转换为UTF-32很容易,而使用UTF-16则更难,因为您也必须处理代理对。 :-P另外,您必须小心拒绝非最短格式,否则在某些情况下它可能会打开安全错误。
我知道这是一年前提出的,但是我不喜欢其他答案,所以我还是要回答。这是我们在源代码中的处理方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| wchar_t * JavaToWSZ(JNIEnv* env, jstring string)
{
if (string == NULL)
return NULL;
int len = env->GetStringLength(string);
const jchar* raw = env->GetStringChars(string, NULL);
if (raw == NULL)
return NULL;
wchar_t* wsz = new wchar_t[len+1];
memcpy(wsz, raw, len*2);
wsz[len] = 0;
env->ReleaseStringChars(string, raw);
return wsz;
} |
编辑:此解决方案在wchar_t为2字节的平台上很好地工作,某些平台具有4字节的wchar_t,在这种情况下此解决方案将不起作用。
这是我将jstring转换为LPWSTR的方法。
1 2 3 4 5
| const char* nativeString = env->GetStringUTFChars(javaString, 0);
size_t size = strlen(nativeString) + 1;
LPWSTR lpwstr = new wchar_t[size];
size_t outSize;
mbstowcs_s(&outSize, lpwstr, size, nativeString, size - 1); |
我尝试jstring-> char-> wchar_t
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| char* js2c(JNIEnv* env, jstring jstr)
{
char* rtn = NULL;
jclass clsstring = env->FindClass("java/lang/String");
jstring strencode = env->NewStringUTF("utf-8");
jmethodID mid = env->GetMethodID(clsstring,"getBytes","(Ljava/lang/String;)[B");
jbyteArray barr = (jbyteArray)env->CallObjectMethod(jstr, mid, strencode);
jsize alen = env->GetArrayLength(barr);
jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
if (alen > 0)
{
rtn = (char*)malloc(alen + 1);
memcpy(rtn, ba, alen);
rtn[alen] = 0;
}
env->ReleaseByteArrayElements(barr, ba, 0);
return rtn;
}
jstring c2js(JNIEnv* env, const char* str) {
jstring rtn = 0;
int slen = strlen(str);
unsigned short * buffer = 0;
if (slen == 0)
rtn = (env)->NewStringUTF(str);
else {
int length = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)str, slen, NULL, 0);
buffer = (unsigned short *)malloc(length * 2 + 1);
if (MultiByteToWideChar(CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length) > 0)
rtn = (env)->NewString((jchar*)buffer, length);
free(buffer);
}
return rtn;
}
jstring w2js(JNIEnv *env, wchar_t *src)
{
size_t len = wcslen(src) + 1;
size_t converted = 0;
char *dest;
dest = (char*)malloc(len * sizeof(char));
wcstombs_s(&converted, dest, len, src, _TRUNCATE);
jstring dst = c2js(env, dest);
return dst;
}
wchar_t *js2w(JNIEnv *env, jstring src) {
char *dest = js2c(env, src);
size_t len = strlen(dest) + 1;
size_t converted = 0;
wchar_t *dst;
dst = (wchar_t*)malloc(len * sizeof(wchar_t));
mbstowcs_s(&converted, dst, len, dest, _TRUNCATE);
return dst;
} |
相当简单。但不要忘记通过ReleaseStringChars释放内存
1 2 3 4 5 6
| JNIEXPORT jboolean JNICALL Java_TestClass_test(JNIEnv * env, jobject, jstring string)
{
const wchar_t * utf16 = (wchar_t *)env->GetStringChars(string, NULL);
...
env->ReleaseStringChars(string, utf16);
} |
只需使用env-> GetStringChars(myString,0);
Java本质上通过Unicode
如果我们对跨平台功能不感兴趣,则可以在Windows中使用MultiByteToWideChar函数或有用的宏A2W(请参见示例)。
|