代码之家  ›  专栏  ›  技术社区  ›  abr

在android studio JNI函数中使用jint和jstring

  •  0
  • abr  · 技术社区  · 7 年前

    我正在Android Studio中开发一个JNI示例,目标是生成一个随机值并将其传递给本机函数,该函数将计算其平方并以这种格式(数字/平方)返回结果。

    我将jint数字作为函数的参数传递,但结果完全错误(显示的结果完全错误)。 这是我的代码:

    按钮生成号码并调用本机函数:

    Button ButtonP = (Button)findViewById(R.id.button3);
            ButtonP .setOnClickListener(
                    new View.OnClickListener()
                    {
                        public void onClick(View view)
                        {
                            Random r = new Random();
                            Integer valeur = 1 + r.nextInt(10 - 1);
                            Log.i("Tag", "Random Value BARRAK " + valeur);
                            TextView tv = (TextView) findViewById(R.id.sample_text);
                            tv.setText(stringFromJNIStop(valeur));
                        }
                    });
    

    本机函数:

    public native String stringFromJNIStop(Integer nombre);
    

    cpp文件中功能的实现:

    extern "C"
    JNIEXPORT jstring JNICALL
    Java_fr_utbm_testjniapplication1_MainActivity_stringFromJNIStop(
            JNIEnv *env,
            jobject, /* this */
            jint nombre) {
        jint CarreNombre = nombre*nombre;
    
        //Convertir le carré en un jstring
        char bufCarreNombre[64];
        sprintf(bufCarreNombre, "%d", CarreNombre);  // error checking omitted
        jstring jStringCarre = (*env).NewStringUTF(bufCarreNombre);
        //Le convertir en un char *
        const char *strCarre= (*env).GetStringUTFChars(jStringCarre,0);
    
        //Convertir le nombre en un jstring
        char bufNombre[64];
        sprintf(bufNombre, "%d", nombre);  // error checking omitted
        jstring jStringNombre = (*env).NewStringUTF(bufNombre);
        //Le convertir en char *
        const char *strNombre= (*env).GetStringUTFChars(jStringNombre,0);
    
        //Concaténer les deux
        char *concatenated;
        concatenated = (char *) malloc(strlen(strNombre) + strlen("/") + strlen(strCarre) + 1);
        strcpy(concatenated, strNombre);
        strcat(concatenated, "/");
        strcat(concatenated, strCarre);
    
        /* Create java string from our concatenated C string */
        jstring retval = (*env).NewStringUTF(concatenated);
    
        //need to release this string when done with it in order to
        //avoid memory leak
        (*env).ReleaseStringUTFChars(jStringNombre,strNombre);
        (*env).ReleaseStringUTFChars(jStringCarre,strCarre);
        /* Free the memory in concatenated */
        free(concatenated);
        return retval;
    
    }
    
    2 回复  |  直到 5 年前
        1
  •  2
  •   user207421    7 年前

    本机函数:

    public native String stringFromJNIStop(Integer nombre);
    

    cpp文件中功能的实现:

    extern "C"
    JNIEXPORT jstring JNICALL
    Java_fr_utbm_testjniapplication1_MainActivity_stringFromJNIStop(
        JNIEnv *env,
        jobject, /* this */
        jint nombre) {
    

    这与您的Java不一致。您已将其从 int Integer 在Java中,无需重新生成。h文件,或者您已经更改或发明了。h文件,无需参考您的。java文件;或者你的。cpp文件与您的不一致。h/。hpp文件。不要这样做。使用 javah 生成您的。h/。hpp文件,并在每次更改中的本机声明时重做它。java文件,并确保。cpp文件同意。h/。hpp文件。它应该是:

    extern "C"
    JNIEXPORT jstring JNICALL
    Java_fr_utbm_testjniapplication1_MainActivity_stringFromJNIStop(
        JNIEnv *env,
        jobject, /* this */
        jobject nombre) {
    

    哪里 nombre 指的是 整数 . 但是,最好将Java本机方法定义为:

    public native String stringFromJNIStop(int nombre);
    

    这将与您现有的一致。cpp。

    也是您的。cpp应 #include 你的h/。水电站。那你就不需要了 extern "C" JNI_EXPORT JNI_CALL ,编译器可能已检测到之间的签名不一致。cpp和。h/。水电站。

        2
  •  -2
  •   abr    7 年前

    经过一些反思,问题得到了解决,事实上,为了使用jint实现JNI函数,我们必须在JAVA部分采用精确的转换规则,所以我们必须将随机值声明为长值,而不是将其声明为整数!因此,我们必须做以下工作:

    long valeur = 1 + r.nextInt(10 - 1);