如何通过C和Java之间的一个复杂的结构,JNI在Android NDK [英] How to pass a complex structure between C and Java with JNI on Android NDK

查看:211
本文介绍了如何通过C和Java之间的一个复杂的结构,JNI在Android NDK的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的Andr​​oid应用程序在C code复杂strucutre,我想在Java端使用它。
我做了一些研究与谷歌和计算器,所以我已经从我的C strucutre创建的Java类,但现在怎么把它在Java中。

I have a complex strucutre in the C code on my Android application and I would like to use it in the Java side. I've done some research with google and in stackoverflow, so I've created the java class from my C strucutre, but now how to get it in Java.

我发现这些信息,有关在类制作的指针和使用在C端:

I've found these informations, about making a pointer in the class and use this on the C side :

Get the field ID : (*env)->GetFieldID(...)
Get the pointer : (*env)->GetLongField(...)
Set the pointer : (*env)->SetLongField(...)

但我不明白它到底是如何工作...

But I don't understand how it really works ...

在上面,你可以找到我所做的事情到现在......没有那么多!
在C面:

Above, you can find what I've done until now ... not so much ! On the C side :

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方面:

And on the Java side :

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");
}

编辑:我想补充一点,我的结构非常复杂那样:

EDIT : I want to add that my structure is very complex like that :

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;

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

Even more complex, just an example to show you how it is !

推荐答案

您无法通过原始的C结构到Java,并期望它把这些结构为类。您需要创建一个类的结构。我看你已经做到了,所以你需要做的唯一的事情就是这个结构转换为类的一个实例。

You cannot pass raw C structs into Java and expect it to treat these structs as classes. You need to create a class for your struct. I see you already did that, so the only thing you need to do is to convert this struct into an instance of the class.

在Java端的code:

The code on the Java side:

public static native ComplexClass listenUDP();

将转化为:

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

在C code,你需要使用 env-&GT加载ComplexClass;的findClass(); 功能。然后创建该类的一个新实例(它简化问题,如果你有零参数的构造函数),你需要在加载的构造方法的签名和激活它 env-> NewObject的() 方法。全code:

In that C code, you need to load the ComplexClass using the env->FindClass(); function. Then to create a new instance of that class (it simplifies matters if you have zero-parameter constructor), you need to load a constructor method signature and "invoke" it in the env->NewObject() method. Full code:

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-&GT; setXXXField(); 。如果您有更多的对象作为字段,要创建ALSE他们,然后重复上述过程的另一个对象。

Then you need to set the fields of this class using env->setXXXField();. If you have more objects as fields and want to alse create them, then repeat the above process for another object.

这看起来很复杂,但这是在Java的管理code。使用本机C的价格。

This looks very complicated, but that's the price for using native C in managed Java code.

这篇关于如何通过C和Java之间的一个复杂的结构,JNI在Android NDK的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆