如何在 JNI 中将 C 结构来回传递给 Java 代码? [英] How to pass C structs back and forth to Java code in JNI?
问题描述
我有一些 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屋!