如何用Valist从C调用java vararg方法

Pav*_*tam 9 java java-native-interface variadic-functions

我有Varargs的C方法

void message(int id,  ...) 
Run Code Online (Sandbox Code Playgroud)

它应该用vararg调用Java静态方法

public static void message(String messageName, String ... args)
Run Code Online (Sandbox Code Playgroud)

我怎么能用C valist和JNI API来做呢?

谢谢!

Jav*_*a42 9

您不可能将va_list的地址传递给Java.以下是一些片段,展示了如何使用"..."和va_list传递数组.根据需要添加错误/异常/返回检查.

在Java中:

static private void javaDefineArray(Object ... args) { 
    for (Object o : args) {
        print("javaDefineArray " + o);
    }
}
Run Code Online (Sandbox Code Playgroud)

在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);
}
Run Code Online (Sandbox Code Playgroud)

C用法:

javaDefineArray(env, o, "0", "1", "2", "3", "4", NULL);
Run Code Online (Sandbox Code Playgroud)

Java输出:

javaDefineArray 0
javaDefineArray 1
javaDefineArray 2
javaDefineArray 3
javaDefineArray 4
Run Code Online (Sandbox Code Playgroud)