6pa*_*kid 6 c++ java generics java-native-interface
是否可以使用带有泛型参数的JNI调用本机CPP函数?类似于以下内容:
public static native <T, U, V> T foo(U u, V v);
Run Code Online (Sandbox Code Playgroud)
然后把它称为:
//class Foo, class Bar, class Baz are already defined;
Foo f = foo(new Bar(), new Baz());
Run Code Online (Sandbox Code Playgroud)
任何人都可以请我提供一个实际上正在进行此操作的示例或网上的一些教程吗?我问,因为在我的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);
}
Run Code Online (Sandbox Code Playgroud)
编辑:
我试过修改代码,但现在我得到NoSuchMethodError:
Java代码:
public static native <U, V> String foo(U u, V v);
//...
String str = foo(new Bar(), new Baz());
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
这是否意味着JNI不支持泛型或者我错过了什么?
通常,您应该始终使用javap -s来获取您将要在JNI中查找的方法的签名.不要猜.
关于堆栈溢出的类型擦除有很多问题(例如,获取泛型类型的java.util.List),你要做的事既不是JNI也不是Java本身.foo的运行时类型签名是(在两个世界中,或实际上,只有一个世界)Object foo(Object u, Object v),它将对返回值执行隐式类强制转换为您调用它的任何类型.
正如您可能会注意到的那样(并且如您对问题的评论中所述),您无法知道什么类型T.
编辑:
顺便说一句,getFoo方法应该返回'Foo',所以你不应该这样做
jmethodID getFooMethod = env->GetMethodID(bar_class, "getFoo", "()LFoo;");
Run Code Online (Sandbox Code Playgroud)
想想看,你的整个通话序列似乎不合适......你有一个foo原生的,返回的字符串.现在foo寻找getFoo的Bar,返回"富",并返回该呼叫直接的结果,有效地试图返回Foo(Foo getFoo()根据注释),其中串的预期.