Вопрос:

используя jint и jstring в функции JNI студии android

android c++ java-native-interface native

449 просмотра

2 ответа

11 Репутация автора

Я работаю над примером JNI в Android Studio, цель которого - сгенерировать случайное значение и передать его в собственную функцию, которая вычислит ее квадрат и вернет результат в этом формате (число / квадрат).

Я передаю номер 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;

}
Автор: abr Источник Размещён: 08.01.2018 10:34

Ответы (2)


-2 плюса

11 Репутация автора

После некоторого размышления проблема была решена, фактически, чтобы реализовать функцию JNI с использованием jint, мы должны принять точные правила преобразования в части JAVA, поэтому вместо объявления случайного значения как целого числа мы должны объявить его как вместе ! поэтому мы должны работать следующим образом:

long valeur = 1 + r.nextInt(10 - 1);
Автор: abr Размещён: 09.01.2018 01:03

2 плюса

267331 Репутация автора

Решение

Родная функция:

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относится к Integer. Однако было бы лучше и всегда было бы лучше определить свой собственный Java-метод следующим образом:

public native String stringFromJNIStop(int nombre);

который теперь согласится с вашим существующим .cpp.

Также ваш .cpp должен #includeваш .h / .hpp. Тогда вам бы не понадобилось extern "C"или JNI_EXPORTили JNI_CALL, и компилятор, возможно, обнаружил несоответствие сигнатур между .cpp и .h / .hpp.

Автор: user207421 Размещён: 09.01.2018 04:08
Вопросы из категории :
32x32