2012-04-24 8 views
9

Tôi có một cấu trúc phức tạp trong mã C trên ứng dụng Android của mình và tôi muốn sử dụng nó ở phía Java. Tôi đã thực hiện một số nghiên cứu với google và trong stackoverflow, vì vậy tôi đã tạo lớp java từ strucutre C của tôi, nhưng bây giờ làm thế nào để có được nó trong Java.Cách chuyển cấu trúc phức tạp giữa C và Java với JNI trên Android NDK

tôi đã tìm thấy những thông tin, về việc một con trỏ trong lớp và sử dụng ở phía bên C:

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

Nhưng tôi không hiểu tại sao nó thực sự hoạt động ...

Ở trên, bạn có thể tìm thấy những gì tôi đã làm cho đến bây giờ ... không quá nhiều! Về phía 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; 
} 

Và ở phía bên 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"); 
} 

EDIT: Tôi muốn nói thêm rằng cấu trúc của tôi là rất phức tạp như thế:

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; 

Thậm chí nhiều hơn phức tạp, chỉ là một ví dụ để cho bạn thấy nó như thế nào!

Trả lời

8

Bạn không thể chuyển cấu trúc C thô vào Java và mong đợi nó xử lý các cấu trúc này dưới dạng lớp. Bạn cần tạo một lớp cho cấu trúc của bạn. Tôi thấy bạn đã làm điều đó, vì vậy điều duy nhất bạn cần làm là chuyển đổi cấu trúc này thành một thể hiện của lớp.

Mã ở phía Java:

public static native ComplexClass listenUDP(); 

sẽ dịch để:

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

Trong đó mã C, bạn cần phải nạp ComplexClass sử dụng env->FindClass(); chức năng. Sau đó, để tạo một cá thể mới của lớp đó (nó đơn giản hóa các vấn đề nếu bạn có hàm tạo tham số 0), bạn cần nạp một chữ ký phương thức khởi tạo và "gọi" nó theo phương thức env->NewObject(). Toàn bộ mã:

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); 

Sau đó, bạn cần đặt các trường của lớp này bằng cách sử dụng env->setXXXField();. Nếu bạn có nhiều đối tượng hơn là các trường và muốn tạo ra chúng, hãy lặp lại quy trình trên cho một đối tượng khác.

Điều này có vẻ rất phức tạp, nhưng đó là giá cho việc sử dụng C gốc trong mã Java được quản lý.

+0

Ok, cảm ơn bạn rất nhiều vì câu trả lời của bạn, nó rất hữu ích. Như bạn nói, nó rất phức tạp, tôi nghĩ rằng có thể sao chép cấu trúc đến lớp một cách dễ dàng, nhưng nó không phải ... Bởi vì cấu trúc của tôi có rất nhiều đối tượng/trường, vì vậy nếu tôi phải thêm tất cả các tham số, tôi sẽ vượt qua ngày trên đó. Vì vậy, nó đơn giản nhất để nhận trực tiếp trong Java gói UDP từ ứng dụng C của tôi? Cảm ơn bạn rất nhiều @Jakub Zaverka – Bibu

+1

@Martin Hãy xem Datagrams: http://docs.oracle.com/javase/tutorial/networking/datagrams/index.html –

+0

Có Tôi biết cách sử dụng DatagramSocket et DatagramPacket, nhưng Tôi không biết làm thế nào để lấy lại dữ liệu của tôi :), cho một String nó khá đơn giản, nhưng đối với một cấu trúc ... – Bibu