gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:58:02 28 4
gpt4 key购买 nike

我的 Android 应用程序的 C 代码中有一个复杂的结构,我想在 Java 端使用它。我用谷歌和 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;

更复杂,只是一个例子来告诉你它是怎么回事!

最佳答案

您不能将原始 C 结构传递给 Java 并期望它把这些结构当作类来对待。您需要为您的结构创建一个类。我看到你已经这样做了,所以你唯一需要做的就是将这个结构转换为类的一个实例。

Java端代码:

public static native ComplexClass listenUDP();

将转化为:

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

在该 C 代码中,您需要使用 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 代码中使用 native C 的代价。

关于java - 如何在 Android NDK 上使用 JNI 在 C 和 Java 之间传递复杂结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10300039/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com