我有一些通过JNI调用的C函数,这些函数使用指向一个 struct 的指针,还有一些其他函数将分配/释放指向同一类型 struct 的指针,这样处理包装器就更容易了.令人惊讶的是,JNI文档很少涉及如何处理C struct .

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

不幸的是,此代码在达到createNewMyStruct()后立即使JVM崩溃.我对JNI还是个新手,不知道会有什么问题.

Edit:我应该注意到,C代码是非常普通的C,经过良好测试,并且是从一个正在工作的iPhone项目移植而来的.此外,该项目使用的是Android NDK框架,它允许您从JNI内的Android项目运行原生C代码.然而,我不认为这是严格意义上的NDK问题...这似乎是我的JNI设置/初始化错误.

推荐答案

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.

C++相关问答推荐

如何判断宏参数是否为C语言中的整型文字

增加getaddrinfo返回的IP地址数量

我无法让LLDB正确运行我的可执行文件

GTK函数调用将完全不相关的char* 值搞乱

为 struct 中的数组动态分配内存时出错

添加函数会 destruct 嵌入式C代码(无IDE)

在vfork()之后,链接器如何在不 destruct 父内存的情况下解析execve()?

Printf()在C中打印终止字符之后的字符,我该如何解决这个问题?

CS50判断灯泡运动的问题,判断时多出一个灯泡,但不在终端上

C语言中奇怪的输出打印数组

从文件到链表读取日期

我错误地修复了一个错误,想了解原因

令人困惑的返回和 scanf 问题相关

C 和 C++ 标准如何告诉您如何处理它们未涵盖的情况?

无法理解 fgets 输出

如何找出C中分配在堆上的数组的大小?

memcmp 是否保证按顺序比较字节?

将十六进制值或十进制值分配给 uint16_t 有什么区别?

C 程序调用 malloc 导致总线错误?

C语言中数组变量是如何存储的? (不是内存本身,而是命名变量中的指针)