14

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;

さらに複雑ですが、それがどのようになっているのかを示すための単なる例です!

4

1 に答える 1

7

生の C 構造体を Java に渡して、Java がこれらの構造体をクラスとして扱うことを期待することはできません。構造体のクラスを作成する必要があります。既にそれを行っているようです。必要なのは、この構造体をクラスのインスタンスに変換することだけです。

Java 側のコード:

public static native ComplexClass listenUDP();

に変換されます:

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

その C コードでは、関数を使用して 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();。フィールドとしてさらにオブジェクトがあり、それらも作成したい場合は、別のオブジェクトに対して上記のプロセスを繰り返します。

これは非常に複雑に見えますが、マネージ Java コードでネイティブ C を使用する代償です。

于 2012-04-24T15:26:49.940 に答える