2012-04-24 14 views
9

AndroidアプリケーションのCコードに複雑な構造があり、Java側で使用したいと考えています。 私はGoogleとstackoverflowでいくつかの研究を行ったので、私はCのstrucutreからJavaクラスを作成しましたが、今はどのようにJavaでそれを取得します。AndroidでJNIを使​​用してCとJavaの複合構造を渡す方法NDK

私はクラスのポインタを作り、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

Javaに未処理のC構造体を渡すことはできず、これらの構造体をクラスとして扱うことはできません。構造体のクラスを作成する必要があります。私はあなたがすでにそれをしているのを見るので、この構造体をクラスのインスタンスに変換するだけです。

Java側のコード:

public static native ComplexClass listenUDP(); 

がに変換されます:そのCコードで

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

は、あなたが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に構造をコピーすることが可能だと思ったが、それはない...私の構造は、オブジェクト/フィールドがたくさんあるので、手動ですべてのパラメータを追加する必要がありますそれで数日を過ごすでしょう。だから、私のCアプリケーションからJavaのUDPパケットを直接受信するのは簡単ですか?ありがとうございます@Jakub Zaverka – Bibu

+1

@Martin Datagramsを見てください:http://docs.oracle.com/javase/tutorial/networking/datagrams/index.html –

+0

はい私はDatagramSocket et DatagramPacketの使い方を知っていますが、私はどのように私のデータを取得するのかわかりません:)、それは非常にシンプルですが、構造体のための文字列のために... – Bibu

関連する問題