我试图返回使用 UTF-8 编码的 jstring,但应用程序崩溃并且 JNI 写出错误:
JNI DETECTED ERROR IN APPLICATION: input is not valid Modified UTF-8: illegal continuation byte 0x30
我的 fragment :
jstring Java_tgio_rncryptor_RNCryptorNative_generateKey(JNIEnv *env, jobject instance, const jstring salt_, const jstring password_)
{
const char *salt = env->GetStringUTFChars(salt_, 0);
const char *password = env->GetStringUTFChars(password_, 0);
RNCryptor *cryptor = new RNCryptor();
string value = (char * )cryptor->generateKey(salt, password).data();
delete cryptor;
env->ReleaseStringUTFChars(salt_, salt);
env->ReleaseStringUTFChars(password_, password);
return env->NewStringUTF(value.c_str());
}
还试过:
const char *returning = env->GetStringUTFChars(env->NewStringUTF(value.c_str()), 0);
return env->NewStringUTF(returning);
有什么建议吗?
最佳答案
cryptor->generateKey
返回 SecByteBlock
,一个字节序列。虽然转换为 (char *)
并构建 std::string
是有意义的,因为它们不仅仅处理文本,jstring
包含文本(来自 UTF-16 编码中的 Unicode 字符集)。
您的代码尝试将非文本字节转换为 Java 字符串。如果你真的想这样做,你必须使用一个字符集和编码,0-255 的任何值序列都有效。 (CP437 就是一个。)
但相反,您可以将数据保持在更接近其本身的数据类型中:返回 Java byte[]
。然后在 Java 端,您可以将字节序列转换为 Base 64 ,如果您想将 key 作为字符串传递。
通常,密码算法对字节序列或 block 进行操作。它只是处理文本的应用程序或包装函数。您将检查 RNCryptor 是否为您执行此操作,但在我看来并非如此。
关于java - 无法在 JNI 中编码为 UTF-8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38030959/