编辑:
抱歉,我误解了您的问题。您可以通过使用 JNI API 提供的其他两种创建对象的方式(来自docs)来实现这一点:
jobject NewObjectA(JNIEnv *env, jclass clazz,
jmethodID methodID, const jvalue *args);
jobject NewObjectV(JNIEnv *env, jclass clazz,
jmethodID methodID, va_list args);
NewObjectA
程序员将所有要传递给构造函数的参数放在一个 jvalue 的 args 数组中,该数组紧跟在 methodID 参数之后。 NewObjectA() 接受此数组中的参数,然后将它们传递给程序员希望调用的 Java 方法。
NewObjectV
程序员将所有要传递给构造函数的参数放在紧跟在 methodID 参数之后的 va_list 类型的 args 参数中。 NewObjectV() 接受这些参数,然后将它们传递给程序员希望调用的 Java 方法。
所以,我制作了一个示例程序来展示如何使用它。
Foo.java
public class Foo {
private int bar;
private String baaz;
public Foo(int bar) {
this(bar, "");
}
public Foo(int bar, String baaz) {
this.bar = bar;
this.baaz = baaz;
}
public void method1() {
this.bar++;
System.out.println(bar);
System.out.println(baaz);
}
}
Bar.java
public class Bar {
public Bar() {
}
public static native Foo createFoo(String signature, Object ... params);
}
Bar.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Bar */
#ifndef _Included_Bar
#define _Included_Bar
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Bar
* Method: createFoo
* Signature: (Ljava/lang/String;[Ljava/lang/Object;)LFoo;
*/
JNIEXPORT jobject JNICALL Java_Bar_createFoo
(JNIEnv *, jclass, jstring, jobjectArray);
#ifdef __cplusplus
}
#endif
#endif
Bar.c
#include "Bar.h"
#include <stdlib.h>
jobject JNICALL Java_Bar_createFoo
(JNIEnv * env, jclass class, jstring signature, jobjectArray params) {
// method signature in char *
const char * signatureChar = (*env)->GetStringUTFChars(env, signature, 0);
jvalue * args;
int i, size;
// retrieve foo class
jclass fooClass = (*env)->FindClass(env, "LFoo;");
// retrieve foo construtor
jmethodID fooConstructor = (*env)->GetMethodID(env, fooClass, "<init>", signatureChar);
// operate over params
// ...
// TODO: find out a way to retrieve size from constructor
size = 2;
args = malloc(size * sizeof(jvalue));
for (i = 0; i < size; i++) {
args[i].l = (*env)->GetObjectArrayElement(env, params, i);
}
return (*env)->NewObjectA(env, fooClass, fooConstructor, args);
}
Main.java
public class Main {
static {
System.loadLibrary("YOUR_LIBRARY_NAME_HERE");
}
public static void main(String[] args) {
Foo foo = Bar.createFoo("(ILjava/lang/String;)V", -12312141, "foo");
System.out.println(foo);
foo.method1();
foo = Bar.createFoo("(I)V", -12312141, "foo");
System.out.println(foo);
foo.method1();
foo = Bar.createFoo("(I)V", -12312141);
System.out.println(foo);
foo.method1();
}
}
警告:它仍然不是 100% 功能性的,因为我不知道如何根据构造函数签名检索构造函数参数大小。