2012-12-21 79 views
2

結構傳遞到Java我必須通過結構如何從C代碼使用JNI

struct Info { 
    u_int8_t timestamp[8]; 
    u_int32_t a; 
    u_int32_t b; 
    u_int32_t c; 
    ActiveInfo activeInfo[MAX_ACTIVE_SET]; 

    }; 

struct ActiveInfo 
{ 
    u_int8_t is_reference; 
    u_int16_t p; 
    u_int32_t q; 
    u_int8_t r; 
    u_int8_t s; 
    }; 
    typedef struct ActiveInfo ActiveInfo; 

我想這(信息)結構傳遞給我的Java code.I都瞪大眼睛,但沒有得到完整的方式去做這個。

謝謝。

回答

4

結構必須在Java方面來定義,與成員的類。 事實上,JNI允許C訪問Java對象,但不允許Java訪問C對象(結構體)。因此,如果您想通過JNI「傳遞」某些內容並使其可以訪問,則它必須是Java對象,然後在界面中限定爲jobject。從C面的話,你有兩個選擇:

  • 或者訪問成員直接與GetFieldID()Get/Set<Type>Field,但它與陣列更加複雜(你有一些我看到的)
  • 或創建Java方法在類用簡化的方式填充和閱讀,並用​​

調用它取決於您的數據存儲設計。您可能只想要一邊(C或Java)讀取,另一邊寫入,這可以方便地反映在設計中。

編輯:www.steveolyo.com

實施例可以在網站上找到由@asgoth指出。有一章叫做「把C結構從C傳遞給Java」,但是它默默地解釋瞭如何在Java類中反映需要的C結構,並通過JNI將Java對象傳遞到C中 - 這正是我的迴應所說的。

+0

謝謝你,你有任何相同的例子。 – Rajendra

2

你需要一個JNIEXPORT:

JNIEXPORT jint JNICALL 
Java_FillCStruct 
(
    JNIEnv *env, 
    jclass obj, 
    jobject info  // EntryInformation object instantiation 
) 
{ 
    testInfo entryInfo; 
    jclass clazz; 
    jfieldID fid; 
    jmethodID mid; 

    GetInfo(entryInfo); // fills in the entryInfo 

    clazz = (*env)->GetObjectClass(env, info); 
    if (0 == clazz) 
    { 
     printf("GetObjectClass returned 0\n"); 
     return(-1); 
    } 
    fid = (*env)->GetFieldID(env,clazz,"index","I"); 

    // This next line is where the power is hidden. Directly change 
    // even private fields within java objects. Nasty! 
    (*env)->SetIntField(env,info,fid,testInfo.index); 
... 

下面是一些例子網站: http://www.steveolyo.com/JNI/JNI.html

1

你已經知道映射的工作只有一個辦法:你可以訪問C/C++的Java類,而不是相反。

但同樣重要的是要記住,這樣的映射包括顯著開銷 - 無論是在內存中,並在CPU。

因此,可能wize放棄完全的透明度。例如,如果只需要讀取activeInfo [n] .s,則可以編寫一個本地方法getais(int n)。或者你可以在Java中以DirectByteBuffer的形式接收整個結構,計算所需的偏移量,並直接操作該值。

+1

感謝你,你有沒有任何例子來做到這一點 – Rajendra