2011-01-12 25 views
2

我有一個C++函數被聲明爲地圖返回類型爲byte [] []中的Java

無符號字符**分類

我使用下列接口文件中SWIG

%module PWrap 
%include "std_string.i" 
%include "arrays_java.i" 

%apply byte[][] {unsigned char**}; 

%{ 
#include "Classifier.h" 
%} 

%include "Classifier.h" 

這產生了一些文件,其中包括SWIGTYPE_p_p_unsigned_char對象

現在,這裏就是我嘗試使用這個C++函數在Java中:

SWIGTYPE_p_p_unsigned_char data = pc.classify();//this works, but I can't do anything with the data object execept pass it to other C++ functions expecting unsigned char** 
byte[][] data2 =pc.classify();//this does not work - throws compile time error 

那麼,我做錯了什麼讓這個映射工作正常?我知道矩陣的維數,因爲我將參數傳遞給C++函數來設置一切。換句話說,只要我能用Java以某種方式將其轉換爲字節,就可以以任何方式獲取數據。

+1

在C++`unsigned char **`中可以指向任何東西。有沒有任何信息如何使用分類功能的結果?例如之後用戶需要釋放內存,用戶應該如何使用矩陣? – ssmir 2011-01-18 15:13:02

+0

用戶不需要釋放它或任何東西 - 只需使用它進入圖像緩衝區 - 一次。 – Derek 2011-01-18 22:15:24

回答

2

我最好使用直接JNI而不是SWIG來完全控制這些數據類型。

無論如何返回char **是無效的,因爲array pinning不能使用。可能這就是爲什麼你的SWIG包裝不能做你想做的 - 你的classify應該接受char **作爲參數,而不是返回它。我不知道SWIG,所以這是一些JNI代碼。

Java源:

Classifier *getClassifierInstance(JNIEnv *env, jobject obj) { 
    jfieldID id = env->GetFieldID(env->GetObjectClass(obj), "_ptr", "J"); 
    return (id == NULL) ? NULL : ((Classifier *)env->GetLongField(obj, id)); 
} 

JNIEXPORT jobjectArray JNICALL 
Java_my_Classifier_classify(JNIEnv *env, jobject obj) { 
    Classifier *classifier = getClassifierInstance(env, obj); 
    char **ptr = classifier->classify(); 
    jobjectArray result = NewObjectArray(env, MATRIX_HEIGHT, FindClass(env, "[B"), NewByteArray(env, 0)); 
    for (int i = 0; i < MATRIX_HEIGHT; ++i) { 
     jbyteArray row = NewByteArray(env, MATRIX_WIDTH); 
     SetByteArrayRegion(env, row, 0, MATRIX_WIDTH, ptr[i]); 
     SetObjectArrayElement(env, result, i, row); 
    } 
    return result; 
} 
3

char **不是字節[] []。只有一維數組可以衰減成指針。你得到的是一個指向數組的指針數組,而不是數組數組。

1

看看http://www.ibiblio.org/pub/languages/fortran/append-c.html 「爲什麼一個雙指針不能被用作一個二維數組」:在C/C++

package my; 

public class Classifier { 
    public native void init(); // initialize _ptr with a new Classifier 
    public native void cleanup(); // destroy Classifier 
    public native byte[][] classify(); 
    private long _ptr; 
} 

方法定義