JNI-从jstring到字节的传输,从字节到字符串的传输问题
JNI - transfer from jstring to byte, from byte to string issue
我在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++方面不是。
在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中的字符串编码问题,请参阅此。