我在转换JNI时遇到问题。
在C ++中,我正在使用AES(Library CryptoPP)创建一些密码。我正在将结果转换为字符串并将其返回。这是获取字符串的代码的样子:
JNIEXPORT jbyteArray JNICALL Java_com_example_androidake_MutualAuthenticateChip_prepareEncryptionCPP
(JNIEnv *env, jobject thisObj, jboolean hmm, jboolean jinit) {
string encryption= mac->EncryptCertKey();
jbyteArray returns = env->NewByteArray(encryption.size());
env->SetByteArrayRegion(returns, 0, encryption.length(), (jbyte*) encryption.c_str());
return returns;
};
上面的字符串正在转换为返回的jbyteArray。首先,我想要使用
返回字符串env->NewStringUTF(encryption.c_str());
但应用程序崩溃了。我认为这是由变量'加密'的内容引起的。我正在使用env-> NewStringUTF(encryption.c_str());在其他函数中,返回的字符串例如只是一个数字或类似的东西。
然后在Java中我正在从字节转换为字符串:
byte[] cipher = mac_A.prepareEncryptionCPP(true, true);
string cipher_str = new String(cipher);
我将该字符串再次添加到C ++对象中,并将旧密码与从Java发送的密码进行比较:
//Java
boolean result = mac_A.compareEncryption(true, cipher);
//JNI
JNIEXPORT jboolean JNICALL Java_com_example_androidake_MutualAuthenticateChip_compareEncryption
(JNIEnv * env, jobject thisObj, jboolean jinit, jstring cipher){
bool init = jinit;
bool result;
jsize length = env->GetStringUTFLength(cipher);
const char *inCStr_ek = env->GetStringUTFChars(cipher, 0);
string s(inCStr_ek, length);
result = mac->CompareCipher(s);
env->ReleaseStringUTFChars(cipher, inCStr_ek);
return result;
};
在C ++中比较:
bool MyClass::CompareCipher(std::string cipher_2){
if(cipher == cipher_2){
return true;
}else{
return false;
}
}
它总是返回false。我不知道我做错了什么。我甚至已经将这个密码从Java发送到C ++并将其恢复为Java并且字符串是相等的,但在C ++方面却没有。
答案 0 :(得分:1)
你的java端代码
byte[] cipher = mac_A.prepareEncryptionCPP(true, true);
boolean result = mac_A.compareEncryption(true, cipher);
compareEncryption
jni函数是用jstring定义的,而不是jbytearray。
所以从JNI方面你要向java发送一个字节数组,从java端你将相同的字节数组发送回本机端(但在调用中使用jstring),但是你使用env->GetStringUTFChars(cipher, 0)
转换该字节数组转换为修改后的UTF-8字符串,因此技术上不再是相同的字节数组。
如果你需要字符串在java端进行转换,只需在jni和java之间使用相同的普通字节数组。 Android JNI中的See this for string encoding issues。