2012-04-24 59 views
9

我的Android應用程序的C代碼中有一個複雜的結構體,我想在Java端使用它。 我已經做了一些谷歌和在stackoverflow的研究,所以我從我的C strucutre創建了Java類,但現在如何獲得它在Java中。如何在Android和NDK上通過JNI在C和Java之間傳遞複雜結構

我發現這些信息,有關在類製作的指針和使用的C面:

Get the field ID : (*env)->GetFieldID(...) 
Get the pointer : (*env)->GetLongField(...) 
Set the pointer : (*env)->SetLongField(...) 

但我不明白它是如何工作...

在上面,你可以找到我迄今爲止所做的...不是太多! 在C面:

ComplexStructure Java_com_main_MainActivity_listenUDP(JNIEnv* env, jclass clazz) 
{ 
    int i,taille; 
    ComplexStructure myStruct;  
    taille = -1;  
    taille = recvfrom(socket, &myStruct, sizeof(ComplexStructure), 0, &rcvAddr, &sizeOfSock); 
    if(taille != -1) 
    { 
     return myStruct; 
    } 
    return NULL; 
} 

而且在Java端:

public void getFromUDP() { 

    ComplexClass myClass = new ComplexClass(); 
    myClass = listenUDP();    
} 

@Override 
public void run() { 
    initUDP(); 
    getFromUDP(); 
} 


public static native ComplexClass listenUDP(); 
public static native void initUDP(); 
public static native void closeUDP(); 

/** Load jni .so on initialization */ 
static { 
    System.loadLibrary("native-interface"); 
} 

編輯:我想補充一點,我的結構是這樣的非常複雜:

typedef struct{ 
    TYPE_A myStructA; 
    TYPE_B myStructB; 
    TYPE_C myStructC; 
    TYPE_D myStructD; 
}ComplexStructure; 

typedef struct{ 
    float rad; 
    int size; 
    bool isEmpty; 
}TYPE_A; 

typedef struct{ 
    float rad; 
    bool isEmpty; 
    float color; 
    int temp; 
}TYPE_B; 

typedef struct{ 
    int temp; 
    float rain; 
    bool isEmpty; 
}TYPE_C; 

typedef struct{ 
    float rad; 
    int idPerson; 
    bool isOnTime; 
}TYPE_D; 

更復雜的,只是一個例子,向你展示它是如何!

回答

8

您不能將原始C結構傳遞給Java,並期望它將這些結構視爲類。你需要爲你的結構創建一個類。我看到你已經做到了,所以你唯一需要做的就是把這個結構轉換成類的一個實例。

在Java端代碼:

public static native ComplexClass listenUDP(); 

將轉化爲:

JNIEXPORT jobject JNICALL Java_com_main_MainActivity_listenUDP(JNIEnv *env, jclass); 

在這種C代碼,你需要用env->FindClass();函數加載ComplexClass。然後創建該類的新實例(如果您有零參數構造函數,則簡化事務),則需要加載構造方法簽名並在env->NewObject()方法中「調用」它。全碼:

jclass complexClass = env->FindClass("/com/main/ComplexClass"); 
jmethod constructor = env->GetMethodId(complexClass, "<init>", "()com/main/ComplexClass"); //The name of constructor method is "<init>" 
jobject instance = env->NewObject(complexClass, constructor); 

然後,你需要使用env->setXXXField();設置這個類的字段。如果你有更多的對象作爲字段並且想要創建它們,那麼爲其他對象重複上述過程。

這看起來很複雜,但這是在託管Java代碼中使用本機C的代價。

+0

好的,非常感謝您的回答,這非常有幫助。正如你所說,這是非常複雜的,我認爲可以將結構複製到類easly,但它不是......因爲我的結構有很多對象/字段,所以如果我必須手動添加所有參數,我將通過它的日子。那麼,在Java中直接接收來自C應用程序的UDP數據包最簡單嗎?非常感謝你@Jakub Zaverka – Bibu 2012-04-25 09:57:04

+1

@Martin看看Datagrams:http://docs.oracle.com/javase/tutorial/networking/datagrams/index.html – 2012-04-25 10:35:04

+0

是的,我知道如何使用DatagramSocket和DatagramPacket,但我不知道如何讓數據返回:),對於一個字符串來說很簡單,但是對於一個結構... – Bibu 2012-04-25 11:51:05

相關問題