如何在 JNI 中将 C 结构来回传递给 Java 代码? [英] How to pass C structs back and forth to Java code in JNI?

查看:37
本文介绍了如何在 JNI 中将 C 结构来回传递给 Java 代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些 C 函数,我通过 JNI 调用它们,它们带有指向结构的指针,还有一些其他函数将分配/释放指向同一类型结构的指针,以便更容易处理用我的包装纸.令人惊讶的是,JNI 文档很少提到如何处理 C 结构.

I've got some C functions which I am calling through JNI which take a pointer to a structure, and some other functions which will allocate/free a pointer to the same type of structure so that it is a bit easier to deal with my wrapper. Surprisingly, the JNI documentation says very little about how to deal with C structures.

我的 C 头文件如下所示:

My C header file looks like so:

typedef struct _MyStruct {
  float member;
} MyStruct;

MyStruct* createNewMyStruct();
void processData(int *data, int numObjects, MyStruct *arguments);

对应的 JNI C 包装文件包含:

The corresponding JNI C wrapper file contains:

JNIEXPORT jobject JNICALL
Java_com_myorg_MyJavaClass_createNewMyStruct(JNIEnv *env, jobject this) {
  return createNewMyStruct();
}

JNIEXPORT void JNICALL
Java_com_myorg_MyJavaClass_processData(JNIEnv *env, jobject this, jintArray data,
                                       jint numObjects, jobject arguments) {
  int *actualData = (*env)->GetIntArrayElements(env, data, NULL);
  processData(actualData, numObjects, arguments);
  (*env)->ReleaseIntArrayElements(env, data, actualData, NULL);
}

...最后,对应的Java类:

...and finally, the corresponding Java class:

public class MyJavaClass {
  static { System.loadLibrary("MyJniLibrary"); }

  private native MyStruct createNewMyStruct();
  private native void processData(int[] data, int numObjects, MyStruct arguments);

  private class MyStruct {
    float member;
  }

  public void test() {
    MyStruct foo = createNewMyStruct();
    foo.member = 3.14159f;
    int[] testData = new int[10];
    processData(testData, 10, foo);
  }
}

不幸的是,此代码在点击 createNewMyStruct() 后立即使 JVM 崩溃.我对 JNI 有点陌生,不知道可能是什么问题.

Unfortunately, this code crashes the JVM right after hitting createNewMyStruct(). I'm a bit new to JNI and have no idea what the problem could be.

编辑:我应该注意到 C 代码是非常普通的 C,经过充分测试并从一个工作的 iPhone 项目移植而来.此外,该项目使用了 Android NDK 框架,该框架允许您从 JNI 内的 Android 项目运行本机 C 代码.但是,我不认为这严格来说是 NDK 问题……对我而言,这似乎是 JNI 设置/初始化错误.

Edit: I should note that the C code is very vanilla C, is well-tested and was ported from a working iPhone project. Also, this project is using the Android NDK framework, which lets you run native C code from an Android project from within JNI. However, I don't think that this is strictly an NDK issue... it seems like a JNI setup/initialization error on my part.

推荐答案

您需要创建一个与 C 结构体具有相同成员的 Java 类,并通过方法 env->GetIntField、env- 在 C 代码中映射"它们>SetIntField、env->GetFloatField、env->SetFloatField 等等——简而言之,大量的体力劳动,希望已经存在自动执行的程序:JNAerator (http://code.google.com/p/jnaerator) 和 SWIG(http://www.swig.org/).两者各有优劣,选择权在你.

You need to create a Java class with the same members as C struct, and 'map' them in the C code via methods env->GetIntField, env->SetIntField, env->GetFloatField, env->SetFloatField, and so on - in short, lots of manual labor, hopefully there already exist programs that do it automatically: JNAerator (http://code.google.com/p/jnaerator) and SWIG (http://www.swig.org/). Both have their pros and cons, the choice is up to you.

这篇关于如何在 JNI 中将 C 结构来回传递给 Java 代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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