JNI-从jstring到字节的传输,从字节到字符串的传输问题

JNI - transfer from jstring to byte, from byte to string issue

本文关键字:传输 字符串 字节 问题 到字节 JNI- jstring      更新时间:2023-10-16

我在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);

compareEncryptionjni函数是用jstring而不是jbytearray定义的。

因此,从JNI端向java发送一个字节数组,从java端向本机端发送相同的字节数组(但在调用中使用jstring),但随后使用env->GetStringUTFChars(cipher, 0)将该字节数组转换为修改后的UTF-8字符串,因此从技术上讲,它不再是同一个字节阵列。

如果您需要字符串,请在java端进行转换,并在jni和java之间使用相同的纯字节数组。有关Android JNI中的字符串编码问题,请参阅此。