如何通过C和Java之间的复杂结构,JNI在Android NDK(How to pass a co

2019-06-23 22:11发布

我有我的Android应用程序在C代码复杂strucutre,我想在Java端使用它。 我做了一些研究与谷歌和计算器,所以我已经从我的C strucutre创建的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;

更复杂,只是一个例子向你展示它是如何!

Answer 1:

你可以不通过原始C结构到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(); 。 如果您有更多的对象作为领域,并希望ALSE创建它们,然后重复上述过程的另一个对象。

这看起来很复杂,不过那是在托管Java代码使用本地C的价格。



文章来源: How to pass a complex structure between C and Java with JNI on Android NDK