2015-06-16 50 views
0

以下是我的C和Java代碼。 Java調用function1來收集Stringinteger,並使用ResultCollector對象返回它們。 ResultCollector是外部類,換句話說,它不嵌套在ResultCollecter類中。另外,它有三個構造函數。我有其他的函數,與(IF)V簽名的構造函數都很好。另外,第三個構造函數也不能正常工作(即(II)V)。JNI不會使用字符串初始化Class Obj

Java代碼是:

package user.directory; 
public class ResultCollector { 
    private int err; 
    private float resVal; 
    private String resID; 

/** 
* Signature (IF)V 
*/ 
public ResultCollector(int err, float value) { 
    this.err = err; 

    this.resVal = value; 
} 

/** 
* Signature (II)V 
*/ 
public ResultCollector(int err, int value) { 
    this.err = err; 

    this.resVal = (float) value; 
} 

/** 
* Signature (ILjava/lang/;)V 
*/ 
public ResultCollector(int err, char[] id) { 
    this.err = err; 
    this.resID = String.copyValueOf(id); 

} 

public String id() { 
    return resID; 
} 

public int err() { 
    return err; 
} 

public float value() { 
    return resVal; 
} 

public void setParam(int err, String id, float value) { 
    this.err = err; 
    this.resID = id; 
    this.resVal = value; 
} 

} 

和C代碼爲:

JNIEXPORT jobject JNICALL Java_project_function1(
     JNIEnv *env, jobject obj, jint index) { 
    jint t; 
    char *id = C function to return string; 
    t = an error that is needed; 


    if (c == NULL) 
     // throw exception 
     return NULL; 

    jstring name = (*env)->NewStringUTF(env, id); 

    if (name == NULL) 
     // throw exception 
     return NULL; 

    jclass c = (*env)->FindClass(env, 
     "user/directory/ResultCollector"); 
    jmethodID constr = (*env)->GetMethodID(env, c, "<init>", "(ILjava/lang/String;)V"); 

    if (constr == NULL) 
    //cannot get the constructor correctly 
     return NULL; 

    jobject result = (*env)->NewObject(env, c, constr, t, name); 
    return result; 
} 

我的問題是:我怎麼能初始化外部類?這段代碼在哪裏出錯?

回答

1

char[]String不一樣。您的構造函數簽名應該是(I[C)V[表示數組,C是焦炭):

jmethodID constr = (*env)->GetMethodID(env, c, "<init>", "(I[C)V"); 

您還需要通過jcharArray而不是jstring的。您可以創建jcharArray這樣的:

int len = strlen(id); 
jcharArray charArray = (*env)->NewCharArray(env, len); 
(*env)->SetCharArrayRegion(env, charArray, 0, len, id); 

或者,你可以改變你的Java代碼接受的String代替char[]

public ResultCollector(int err, String id) { 
    this.err = err; 
    this.resID = id;  
} 
+1

道德:不自己寫JNI方法簽名。使用'javap -s'的輸出。這絕不是錯的。 – EJP

+0

謝謝samgak!嘗試了不同的方法。我也嘗試過arraychar。儘管我不得不承認你的答案是完全正確的,但你的方法對我並不適用!問題是JNI一次識別其中一個構造函數。所以,我最終爲每個結果定義了三個類。現在,它正在工作。我不確定爲什麼JNI對一些構造函數感到不滿。 –