2010-02-09 138 views
5

是否可以使用JNI調用本地CPP函數,該函數使用泛型參數?像下面這樣:Java泛型和JNI

public static native <T, U, V> 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 <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不支持泛型,或者我錯過了什麼?

+1

JNI不會做任何魔術。與bog標準Java代碼一樣,您將在哪裏創建一個「T」? – 2010-02-09 10:24:16

回答

7

關於堆棧溢出的類型擦除有很多問題(例如Get generic type of java.util.List),您希望做的事對於JNI和Java本身來說都是不可能的。 foo的運行時類型簽名是(在兩個世界中,或者實際上只有一個世界)Object foo(Object u, Object v),它將對返回值進行隱式類轉換,以轉換爲您調用它的任何類型。你可能會注意到(並且正如你的問題的評論中提到的那樣),你無法知道T是什麼類型。

編輯
順便說一句,該方法的getFoo應該返回「富」,所以你不應該做

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

試想想起來了,你的整個調用序列似乎不合適的......你有一個foo這是本地的,返回字符串。現在fooBar中查找getFoo,它返回'Foo',並直接返回該調用的結果,有效地嘗試返回FooFoo getFoo()根據註釋)字符串的預期位置。

8

一般而言,您應該總是使用javap -s來獲取您將在JNI中尋找的方法的簽名。不要猜測。

+2

我不同意。我的本地圖書館有51個功能,我手動編碼它們都沒有問題。如果你只是停下來想一想你正在做什麼,那麼讓它們合適並不難。 – 2010-03-11 07:06:47

+3

但是,爲什麼運行*任何*風險,當你有一個已經100%正確的工具? – EJP 2010-04-06 10:42:44

+2

'javah'將接收一個類文件並輸出一個C頭文件,其中包含您需要實現的確切函數 – 2010-08-12 22:16:08