簡體   English   中英

如何在Android NDK上使用JNI在C和Java之間傳遞復雜的結構

[英]How to pass a complex structure between C and Java with JNI on Android NDK

我的Android應用程序中的C代碼有一個復雜的結構,我想在Java端使用它。 我已經在Google和stackoverflow上進行了一些研究,因此我已經從C結構創建了Java類,但是現在如何在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;

更復雜的是,僅是一個示例向您展示它的狀態!

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

Java方面的代碼:

public static native ComplexClass listenUDP();

將轉換為:

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

在該C代碼中,您需要使用env->FindClass();來加載ComplexClass env->FindClass(); 功能。 然后,要創建該類的新實例(如果您使用零參數的構造函數,它將簡化操作),您需要加載一個構造函數方法簽名,並在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();來設置此類的字段env->setXXXField(); 如果您有更多對象作為字段並且還想創建它們,則對另一個對象重復上述過程。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM