当前位置: 首页 > 面试题库 >

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

强阳曜
2023-03-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;

更复杂的是,仅举一个示例向您展示它的状态!


问题答案:

您不能将原始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代码中使用本机C的代价。



 类似资料:
  • 问题内容: 我一直遵循本文中@tulskiy的建议,通过JNI将Java中的c指针存储在Java中通过JNI在C和Java之间传递指针 诀窍是将指针转换为jlong​​。所以从c我有 我返回一个jlong​​(始终为64位),因为我希望我的代码在64位和32位系统上都能工作。64位计算机上64位指针在内存中的大小为64,而在32位计算机上,内存中指针的大小为32位。 问题是在32位计算机上,我收到

  • 问题内容: 我有一个C结构。 我想将数据从Java映射到C结构,如何使用JNI进行处理?我不会编程Java代码。Java程序员只是想知道他应该以哪种形式向我发送数据?他是否应该期待更多细节 我目前正在通过用包含2列的CSV文件填充结构实例来测试我的代码。 我也想从我的C代码向Java应用程序返回3个double值。 问题答案: 向您的Java程序员提供以下声明: 在您的C代码中,您将能够使用传递的

  • 问题内容: 我有一些通过JNI调用的C函数,这些函数带有指向结构的指针,还有一些其他函数将分配/释放指向相同类型结构的指针,以便处理包装程序更加容易。令人惊讶的是,JNI文档很少介绍如何处理C结构。 我的C头文件如下所示: 相应的JNI C包装文件包含: …最后是对应的Java类: 不幸的是,此代码在点击后立即使JVM崩溃。我对JNI有点陌生,不知道可能是什么问题。 编辑 :我应该注意,C代码非常

  • 问题内容: 我正在努力实现以下目标: 1)我在Java端有一个字节数组,代表一个图像。 2)我需要授予我的本机代码访问权限。 3)本机代码使用GraphicsMagick解码此图像,并通过调用resize创建一堆缩略图。它还计算图像的感知哈希,它可以是矢量或unint8_t数组。 4)一旦我将这些数据返回到Java端,不同的线程将读取它。缩略图将通过HTTP上传到某些外部存储服务。 我的问题是:

  • 问题内容: 抱歉,如果我的问题是菜鸟。我正在使用pgsql 8.4运行Django 1.2,并且需要在从用户处获得输入后运行Java程序,进行一些计算并将结果返回给用户。 我是否可以知道在Java和Python Django之间传递数据的最佳方法是什么,以便解决上述情况?我听说过Jython,但是根据Django文档,它需要扩展名jython- Django,但目前不支持django1.2.x。我

  • 我希望使用Groovy在SOAPUI中执行以下操作: 我在internet上发现一些帖子建议使用groovy属性 但我觉得对我来说还不够。 我希望能够通过以下方式将映射传递到Testcase2: 提前致谢