2017-01-26 15 views
0

Это, как я делаю это для строки:Как я могу отправить int как параметр с помощью getApplicationJniMethodId?

void SampleSwitchCamera(const char *name) 
{ 
    jboolean isAttached; 
    JNIEnv *env; 
    jmethodID mid; 
    jstring js; 
    LOGE("SampleSwitchCamera Begin"); 
    env = getJniEnv(&isAttached); 
    if (env == NULL) 
      goto FAIL0; 

    mid = getApplicationJniMethodId(env, applicationJniObj, "cameraSwitchCallback", "(Ljava/lang/String;)V"); 
    if (mid == NULL) 
      goto FAIL1; 

    js = (*env)->NewStringUTF(env, name); 
    (*env)->CallVoidMethod(env, applicationJniObj, mid, js); 

    if (isAttached) 
    { 
     (*global_vm)->DetachCurrentThread(global_vm); 
    } 
    LOGE("SampleSwitchCamera End"); 
    return; 
FAIL1: 
    if (isAttached) 
    { 
     (*global_vm)->DetachCurrentThread(global_vm); 
    } 
FAIL0: 
    LOGE("SampleSwitchCamera FAILED"); 
    return; 
} 

Так что я попытался так:

void CallbackFromJni(const int *id) 
{ 
jboolean isAttached; 
JNIEnv *env; 
jmethodID mid; 
jstring js; 
LOGE("callbackFromJni Begin %d", id); 
env = getJniEnv(&isAttached); 
if (env == NULL) 
    goto FAIL0; 

mid = getApplicationJniMethodId(env, applicationJniObj, "callbackFromJni", "(Ljava/lang/Integer;)V"); 
if (mid == NULL) 
    goto FAIL1; 

jintArray array = (*env)->NewIntArray(env, id); 
(*env)->CallVoidMethod(env, applicationJniObj, mid, array); 

if (isAttached) 
{ 
    (*global_vm)->DetachCurrentThread(global_vm); 
} 
LOGE("callbackFromJni End"); 
return; 
FAIL1: 
if (isAttached) 
{ 
    (*global_vm)->DetachCurrentThread(global_vm); 
} 
FAIL0: 
LOGE("callbackFromJni FAILED"); 
return; 
} 

Но я получаю эту ошибку:

01-26 11:17:36.654: E/VidyoMobile app/src/main/jni/ndkVidyoSample.c(22071): callbackFromJni Begin 101 
01-26 11:17:36.655: E/art(22071): JNI ERROR (app bug): attempt to pass an instance of int[] as argument 1 to void com.vidyo.vidyocore.VidyoCoreApplication.callbackFromJni(java.lang.Integer) 
01-26 11:17:36.692: A/art(22071): art/runtime/java_vm_ext.cc:410] JNI DETECTED ERROR IN APPLICATION: bad arguments passed to void com.vidyo.vidyocore.VidyoCoreApplication.callbackFromJni(java.lang.Integer) (see above for details) 
01-26 11:17:36.692: A/art(22071): art/runtime/java_vm_ext.cc:410] native: #09 pc 000024a9 /data/app/be.belfius.videocall-1/lib/arm/libndkVidyoSample.so (CallbackFromJni+104) 
01-26 11:17:37.219: A/art(22071): art/runtime/runtime.cc:366] native: #12 pc 000024a9 /data/app/be.belfius.videocall-1/lib/arm/libndkVidyoSample.so (CallbackFromJni+104) 
01-26 11:17:37.220: A/art(22071): art/runtime/runtime.cc:366] native: #14 pc 000024a9 /data/app/be.belfius.videocall-1/lib/arm/libndkVidyoSample.so (CallbackFromJni+104) 
01-26 11:17:37.365: A/DEBUG(195): Abort message: 'art/runtime/java_vm_ext.cc:410] JNI DETECTED ERROR IN APPLICATION: bad arguments passed to void com.vidyo.vidyocore.VidyoCoreApplication.callbackFromJni(java.lang.Integer) (see above for details)' 
01-26 11:17:37.389: A/DEBUG(195):  #14 pc 000024a9 /data/app/be.belfius.videocall-1/lib/arm/libndkVidyoSample.so (CallbackFromJni+104) 

Я asumming потому что нужно int, и это создает intArray.Как я могу создать Int, потому что нет newInt, просто newIntArray

ответ

1

вы объявили, чтобы получить метод, который получает Integer объект в качестве параметра

середины = getApplicationJniMethodId (окр, applicationJniObj, "callbackFromJni", «(Ljava/lang/Integer;) V ");

но вы передаете целую таблицу int[] в качестве параметра

jintArray array = (*env)->NewIntArray(env, id); 
(*env)->CallVoidMethod(env, applicationJniObj, mid, array); 

правильный способ объявления типов использования описаны здесь: https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/types.html


если вы хотите передать Integer в качестве параметра, вы необходимо изменить создание таблицы для создания единого объекта Integer

jclass int_cls = (*env)->FindClass(env, "java/lang/Integer"); 
if (int_cls == NULL) 
    goto FAIL1; 

jmethodID int_constructor = (*env)->GetMethodID(env, int_cls, "<init>", "(I)V"); 
if (int_constructor == NULL) 
    goto FAIL1; 

jobject java_int = (*env)->NewObject(env, int_cls, int_constructor, (jint)*id); 
if (java_int == NULL) 
    goto FAIL1; 

(*env)->CallVoidMethod(env, applicationJniObj, mid, java_int); 

метод в Java стороне в этом случае нужно выглядеть следующим образом:

native void callbackFromJni(Integer result); 

вместо Integer было бы намного проще пройти простой int, а не Integer, как примитивные типы могут быть переданы непосредственно вместо того, чтобы бокс их в объектах

mid = getApplicationJniMethodId(env, applicationJniObj, "callbackFromJni", "(I)V"); 
if (mid == NULL) 
    goto FAIL1; 

(*env)->CallVoidMethod(env, applicationJniObj, mid, *id); 

метода в Java стороны в этом случае нужно выглядеть следующим образом:

native void callbackFromJni(int result); 

если вы пытаетесь передать целочисленный массив int[] вам нужно будет объявить

mid = getApplicationJniMethodId(env, applicationJniObj, "callbackFromJni", "([I)V"); 

параметр, передаваемый в создание новой таблицы является размер, а не сам массив, так что вы бы необходимо сначала получить размер этого массива и использовать его при создании таблицы

jintArray array = (*env)->NewIntArray(env, size); 

затем установить содержимое массива и передать его обратный вызов

(*env)->SetIntArrayRegion(env, array, 0, size, id); 
(*env)->CallVoidMethod(env, applicationJniObj, mid, array); 

метод в Java стороне в этом случае нужно выглядеть следующим образом:

native void callbackFromJni(int[] result); 
+0

Очень хорошо поставить: D, спасибо много. Я не понял, как создать java_int для отправки через callVoidMethod, но ваше объяснение прекрасное, и мне удалось исправить мою проблему –

+0

, чтобы создать объект, вам нужно указать ссылку на класс назначения и ссылку на конструктор, а затем передать их 'NewObject (env, clazz_ref, constructor_ref, constructor_params ...)' –

+0

В качестве примера я использовал только IntArray и String, и вы можете создать строку с newStringUTF, я предполагал, что Integer будет иметь что-то подобное, и, увидев, что hasn ' t Я не был уверен, как отправить ссылку на класс –