Javagenerics和JNI

是否可以使用带有generics参数的JNI调用本机CPP函数? 类似于以下内容:

public static native  T foo(U u, V v); 

然后称之为:

 //class Foo, class Bar, class Baz are already defined; Foo f = foo(new Bar(), new Baz()); 

任何人都可以请我提供一个实际上正在做这个或网上教程的样本吗? 我问,因为在我的CPP JNI函数(由JVM调用)中,我得到了不满意的链接错误。

CPP代码如下:

 JNIEXPORT jobject JNICALL Java_Processor_process (JNIEnv *env, jclass processor_class, jobject obj1, jobject obj2) { jclass bar_class = env->FindClass("Bar"); jmethodID getFooMethod = env->GetMethodID(bar_class, "getFoo", "()Ljava/lang/Object;"); //getFoo() is defined as `public Foo getFoo();` in Bar.java return env->CallObjectMethod(obj1, getFooMethod); } 

编辑:

我试过修改代码,但现在我得到NoSuchMethodError:

Java代码:

 public static native  String foo(U u, V v); //... String str = foo(new Bar(), new Baz()); 

CPP代码:

 JNIEXPORT jstring JNICALL Java_Processor_process (JNIEnv *env, jclass processor_class, jobject obj1, jobject obj2) { jclass bar_class = env->FindClass("Bar"); jmethodID getFooMethod = env->GetMethodID(bar_class, "getFoo", "()Ljava/lang/String;"); //getFoo() is now defined as `public String getFoo();` in Bar.java return env->CallObjectMethod(obj1, getFooMethod); } 

这是否意味着JNI不支持generics,或者我错过了什么?

关于堆栈溢出的类型擦除有很多问题(例如, 获取generics类型的java.util.List ),你要做的就是JNI和Java本身都不可能。 foo的运行时类型签名是(在两个世界中,或者实际上,只有一个世界) Object foo(Object u, Object v) ,它将对返回值执行隐式类强制转换为您调用它的任何类型。

正如您可能会注意到的(并且如您对问题的评论中所述),您无法知道T是什么类型。

编辑
顺便说一句,getFoo方法应该返回’Foo’,所以你不应该这样做

 jmethodID getFooMethod = env->GetMethodID(bar_class, "getFoo", "()LFoo;"); 

想想看,你的整个调用序列似乎不合适……你有一个原生的foo ,返回字符串。 现在fooBar查找getFoo ,它返回’Foo’,并直接返回该调用的结果,有效地尝试返回一个Foo (根据注释的Foo getFoo() ),其中字符串是预期的。

通常,您应该始终使用javap -s来获取您将要在JNI中查找的方法的签名。 不要猜。