2012-01-16 20 views
8

tengo método C con varargsCómo llamar al método vararg Java desde C con valist

void message(int id, ...) 

y debe llamar al método estático de Java con vararg

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

¿Cómo puedo hacer que el uso de C valist y JNI API?

¡Gracias!

+2

No es una experto con Java o JNI, pero los varargs de Java son esencialmente Arrays, mientras que C varargs son ... desordenados e inseguros. Es probable que su función C necesite construir correctamente la matriz e invocar la función Java con eso. –

+0

Sí, puedo construir una matriz de objetos, pero espero que exista una solución más agradable. Por ejemplo, la invocación del constructor java tiene un método que recibe Valist C –

+0

@Pavel: creo que estás sobreestimando a JNI. ¿Estás abierto a usar JNA? Sé que puede crear métodos Java varargs que envuelvan las funciones C varargs, no sé si podría hacer lo opuesto. –

Respuesta

7

No es probable que obtenga ningún uso de pasar la dirección de una va_list hasta Java. Aquí hay algunos fragmentos que muestran cómo pasar una matriz usando "..." y va_list. Agregar error/excepción/verificación de retorno según sea necesario.

En Java:

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

En 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 Salida:

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

¿qué sucede si no sabes el tipo de vararg args? digamos que la invocación fue 'javaDefineArray (env, o," 0 ", 1," 56 ", 17.3)'? – 4ntoine

+0

Crea una nueva pregunta y haz referencia a esta pregunta y veamos si alguien puede ayudar con el problema. – Java42

Cuestiones relacionadas