android - 每次调用 JNI 方法时附加值

标签 android c android-ndk java-native-interface

我正在使用 JNI 来获取 apk 的签名,并且我得到了很好的结果。当我第一次从 java 调用这个方法时,我得到了准确的值。再次调用它,我得到带有精确值的附加值(例如 1234456123456)。 PFB 我正在使用的代码

char* getSignatureMd5(JNIEnv* env, jobject obj)
{
    char* sign = loadSignature(env, obj);
    MD5_CTX context = { 0 };
    MD5Init(&context);
    MD5Update(&context, (unsigned char*)sign, strlen(sign));
    unsigned char dest[16] = { 0 };
    MD5Final(dest, &context);
    int i;
    static char destination[32]={0};
    for (i = 0; i < 16; i++) {
            sprintf(destination, "%s%02x", destination, dest[i]);
    }
    return destination;
}

getToken JNI 方法

JNIEXPORT jstring JNICALL Java_com_sign_signaturecapturesbi_MyAdapter_getToken(JNIEnv *env, jobject obj)
                                                                     {
    char* signValue = getSignatureMd5(env, obj);
    __android_log_print(ANDROID_LOG_VERBOSE, "MyApp", "signValue %s", signValue);
    return (*env)->NewStringUTF(env, signValue);
    }

最佳答案

这些行会导致未定义的行为:

for (i = 0; i < 16; i++) {
        sprintf(destination, "%s%02x", destination, dest[i]);
}

man 3 printf :

C99 and POSIX.1-2001 specify that the results are undefined if a call to sprintf(), snprintf(), vsprintf(), or vsnprintf() would cause copying to take place between objects that overlap (e.g., if the target string array and one of the supplied input arguments refer to the same buffer).

此外,destination静态,因此它会在调用之间保留其内容。这些点加在一起会给你带来如此奇怪的行为。

由于dest大小是众所周知的,您可以简单地展开循环,也不要忘记向destination添加一个额外的单元格以终止\0。并且,如果可能的话,您应该使用 snprintf() 来代替:

static char destination[33];

snprintf(destination, sizeof destination,
    "%02x%02x%02x%02x%02x%02x%02x%02x"
    "%02x%02x%02x%02x%02x%02x%02x%02x",
    dest[0], dest[1], dest[2], dest[3],
    dest[4], dest[5], dest[6], dest[7],
    dest[8], dest[9], dest[10], dest[11],
    dest[12], dest[13], dest[14], dest[15]);

在这种情况下,您可以将destination保留为static,因为您的代码不再中继其内容。但请注意,每次调用时,getSignatureMd5()都会返回指向同一缓冲区的指针,因为后续调用的结果会删除先前调用获得的结果。

关于android - 每次调用 JNI 方法时附加值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40521775/

相关文章:

Android studio实验插件0.6.0 NDK调试

android - android.webkit.WebViewClassic.loadDataWithBaseURL 中 Webview 的 Java 空指针异常

android - 在 android-sdk 目录中找不到示例

c++ - Lua 比 C/C++ 更适合的示例用法

C 程序将厘米转换为英寸和英尺

android - 运行编译文件问题 - eh_frame_hdr

java - 通过 JNI 将 C++ 字符串发送到 Java

android - 使用 android-support-v4 替代 PreferenceFragment

android - 您是否检查膨胀 View 是否为空?

c - 从文件中读取并存储在 C 中