Java Generics和JNI

 2023-01-19    340  

问题描述

是否可以使用使用通用参数的JNI调用本机CPP函数?如下:

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

然后将其称为:

Java Generics和JNI

//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 <U, V> 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不支持仿制药,还是我错过了什么?

推荐答案

关于堆栈溢出的类型擦除有很多问题(例如>获取通用类型的java.util.list ),JNI和Java本身都不是可能的. FOO的运行时类型签名是(在两个世界中,实际上,只有一个世界)Object foo(Object u, Object v),它将在返回值上进行隐含的类别,以使其称为任何类型.

您可能会注意到(正如您对问题的评论中提到的),您无法知道哪种类型T是.

编辑:
顺便说一句,GetFoo方法应该返回” foo”,所以您不应该这样做

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

想到这一点,您的整个呼叫顺序似乎不合时宜…您有一个本机,返回字符串的foo.现在foo在Bar中寻找getFoo,它返回’foo’,并直接返回该调用的结果,有效地尝试返回Foo(根据评论) .

其他推荐答案

通常,您应该始终使用Javap -s获取您将要在JNI中寻找的方法的签名.不要猜测.

以上所述是小编给大家介绍的Java Generics和JNI,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/25853.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。