如何在 Android NDK 上使用 JNI 在 C 和 Java 之间传递复杂的结构

How to pass a complex structure between C and Java with JNI on Android NDK(如何在 Android NDK 上使用 JNI 在 C 和 Java 之间传递复杂的结构)
本文介绍了如何在 Android NDK 上使用 JNI 在 C 和 Java 之间传递复杂的结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我的 Android 应用程序的 C 代码中有一个复杂的结构,我想在 Java 端使用它.我在 google 和 stackoverflow 中进行了一些研究,所以我从我的 C 结构创建了 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 方面:

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端代码:

public static native ComplexClass listenUDP();

将转换为:

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

在该 C 代码中,您需要使用 env->FindClass(); 函数加载 ComplexClass.然后要创建该类的新实例(如果您有零参数构造函数,它会简化问题),您需要加载构造函数方法签名并在 env->NewObject() 方法.完整代码:

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->setXXXField();来设置这个类的字段.如果您有更多对象作为字段并想创建它们,则对另一个对象重复上述过程.

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 代码中使用原生 C 的代价.

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

这篇关于如何在 Android NDK 上使用 JNI 在 C 和 Java 之间传递复杂的结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

How to send data to COM PORT using JAVA?(如何使用 JAVA 向 COM PORT 发送数据?)
How to make a report page direction to change to quot;rtlquot;?(如何使报表页面方向更改为“rtl?)
Use cyrillic .properties file in eclipse project(在 Eclipse 项目中使用西里尔文 .properties 文件)
Is there any way to detect an RTL language in Java?(有没有办法在 Java 中检测 RTL 语言?)
How to load resource bundle messages from DB in Java?(如何在 Java 中从 DB 加载资源包消息?)
How do I change the default locale settings in Java to make them consistent?(如何更改 Java 中的默认语言环境设置以使其保持一致?)