小编典典

如何在JNI中将C结构来回传递给Java代码?

java

我有一些通过JNI调用的C函数,这些函数带有指向结构的指针,还有一些其他函数将分配/释放指向相同类型结构的指针,以便处理包装程序更加容易。令人惊讶的是,JNI文档很少介绍如何处理C结构。

我的C头文件如下所示:

typedef struct _MyStruct {
  float member;
} MyStruct;

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

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

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类:

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

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

编辑 :我应该注意,C代码非常原始,经过了充分的测试,并且是从运行中的iPhone项目移植而来的。另外,该项目使用的是Android
NDK框架,该框架使您可以从JNI中的Android项目运行本机C代码。但是,我认为这并不是严格意义上的NDK问题……我看来这似乎是JNI安装/初始化错误。


阅读 212

收藏
2020-09-09

共1个答案

小编典典

您需要创建一个具有与C结构相同成员的Java类,然后通过env-> GetIntField,env-> SetIntField,env->
GetFloatField,env-> SetFloatField等方法在C代码中“映射”它们-
简而言之,大量的体力劳动,希望已经有可以自动执行的程序:JNAerator(http://code.google.com/p/jnaerator)和SWIG(http://www.swig.org/)。两者都有其优缺点,选择取决于您。

2020-09-09