Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How call java vararg method from C with valist

I have C method with varargs

void message(int id,  ...) 

And it should call Java static method with vararg

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

How can I do it using C valist and JNI API?

Thank you!

like image 875
Pavel Bernshtam Avatar asked Jan 16 '12 13:01

Pavel Bernshtam


People also ask

Does Java support varargs?

Varargs were introduced in Java 5 and provide a short-hand for methods that support an arbitrary number of parameters of one type. In this article, we'll see how we can use this core Java feature.

What is varargs in Java with Example?

Varargs is a short name for variable arguments. In Java, an argument of a method can accept arbitrary number of values. This argument that can accept variable number of values is called varargs. The syntax for implementing varargs is as follows: accessModifier methodName(datatype… arg) { // method body }

What is the syntax of variable number of parameters in Java?

Syntax of Varargs A variable-length argument is specified by three periods or dots(…). This syntax tells the compiler that fun( ) can be called with zero or more arguments. As a result, here, a is implicitly declared as an array of type int[].

Which of the following data structure is used by varargs in Java?

The varargs uses ellipsis i.e. three dots after the data type.


1 Answers

Your not likely to get any use out of passing the address of a va_list up to Java. Here are a few snippets showing how to pass up an array using "..." and va_list. Add error/exception/return checking as necessary.

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 Usage:

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

Java Output:

javaDefineArray 0
javaDefineArray 1
javaDefineArray 2
javaDefineArray 3
javaDefineArray 4
like image 179
Java42 Avatar answered Sep 30 '22 18:09

Java42