2012-01-16 13 views
8

ho metodo C con varargsCome chiamare il metodo vararg Java da C con valist

void message(int id, ...) 

e dovrebbe chiamare il metodo statico Java con vararg

public static void message(String messageName, String ... args) 

Come posso farlo utilizzando C valist e API JNI?

Grazie!

+2

Non un esperto con Java o JNI, ma varargs Java sono essenzialmente matrici, mentre varargs C sono ... disordinati e non sicuri. Probabilmente la tua funzione C ha bisogno di costruire correttamente la matrice e invocare la funzione Java con quella. –

+0

Sì, posso costruire un array di oggetti, ma mi aspetto che esista una soluzione più bella. Ad esempio, il richiamo del costruttore java ha un metodo che riceve C valist –

+0

@Pavel: Penso che tu stia sopravvalutando JNI. Sei aperto all'utilizzo di JNA? So che può creare metodi varargs Java che avvolgono le funzioni di varargs di C, non so se sarebbe in grado di fare il contrario. –

risposta

7

È improbabile che venga utilizzato l'indirizzo di va_list fino a Java. Ecco alcuni snippet che mostrano come passare un array usando "..." e va_list. Aggiungi errore/eccezione/controllo di ritorno secondo necessità.

In Java:

static private void javaDefineArray(Object ... args) { 
    for (Object o : args) { 
     print("javaDefineArray " + o); 
    } 
} 

In C:

// Lookup the method using GetMethodID or GetStaticMethodID 
mid = (*env)->GetStaticMethodID(env, class, "javaDefineArray", "([Ljava/lang/Object;)V"); 

// C function taking variable args (all String in this example) 
static void javaDefineArray(JNIEnv * env, jobject o, ...) { 
    int i = 0; 
    int count = 0; 
    char * msg[100+1] = {0}; // 100 args max 
    jobjectArray ja; 
    va_list list; 
    va_start(list, o); 
    do {msg[count] = va_arg(list,char *); 
    } while(msg[count] !=0 && ++count < 100); // end/saftey check 
    va_end(list); 
    ja = (*env)->NewObjectArray(env, count, (*env)->FindClass(env, "java/lang/String"), (*env)->NewStringUTF(env, "")); 
    for(i=0;i!=count;i++) { 
    (*env)->SetObjectArrayElement(env,ja,i,(*env)->NewStringUTF(env, msg[i])); 
    } 
    (*env)->CallVoidMethod(env, o, mid, ja); 
} 

C Uso:

javaDefineArray(env, o, "0", "1", "2", "3", "4", NULL); 

Java uscita:

javaDefineArray 0 
javaDefineArray 1 
javaDefineArray 2 
javaDefineArray 3 
javaDefineArray 4 
+0

cosa succede se non si conosce il tipo argarg di vararg? diciamo invocazione era 'javaDefineArray (env, o," 0 ", 1," 56 ", 17.3)'? – 4ntoine

+0

Crea una nuova domanda e fai riferimento a questa domanda e vediamo se qualcuno può aiutarti con il problema. – Java42

Problemi correlati