我在C和Java之间使用多参数类型映射到byte[]
映射了一系列参数,但每当我在ReleaseByteArray
中调用wrapper
时,我都会收到以下错误。 。
`java'出错:free():下一个大小无效(快):0x00007f1a70174610 ***
======= Backtrace:=========
/lib64/libc.so.6(+0x7d023)[0x7f1a75da9023]
/usr/java/jdk1.8.0_74/jre/lib/amd64/server/libjvm.so(+0x6d9ab6)[0x7f1a75425ab6]
/usr/lib/libtesting.so(Java_com_testing_foo_jni_1foo+0x639)[0x7f1a192d03f6]
[0x7f1a60dfa994]
此外,如果我删除释放调用,foo返回但输出数组(arg1)在返回时尚未修改,可能是因为未调用ReleaseByteArray。
我的'swigging'不是最好的,但我已成功使用carrays并传递单个参数来包装此函数。我真的想通过Java传递三个字节数组,并且想要使用多参数类型映射,但无法找到错误的来源。
Valgrind在使用C时没有显示C中的内存错误或泄漏。
这可能是Java中垃圾收集的问题吗?线程问题?
感谢您的指导!希望我的打字示例可以帮助其他人。
(所有代码如下)
我在C中使用以下函数来包装SWIG:
int foo(
unsigned char *out, unsigned long long *out_len,
const unsigned char *a, unsigned long long alen,
const unsigned char *b
)
从Java调用foo,out以适当的大小提供,并且应该在返回时填充字节...
void foo(byte[] out, byte[] a, byte[] b) <-- out should be filled on return.
我的“out”类型图:(来自swig docs的多参数结构)。我有其他参数的类似地图。
/* unsigned char *, unsigned long long * */
%typemap(jni) (unsigned char *out, unsigned long long *out_len) "jbyteArray"
%typemap(jtype) (unsigned char *out, unsigned long long *out_len) "byte[]"
%typemap(jstype) (unsigned char *out, unsigned long long *out_len) "byte[]"
%typemap(in,numinputs=1) (unsigned char *out, unsigned long long *out_len){
$1 = JCALL2(GetByteArrayElements, jenv, $input, 0);
unsigned long long tp = JCALL1(GetArrayLength, jenv, jarg1);
$2 = &tp;
}
%typemap(argout) (unsigned char *out, unsigned long long *out_len){
JCALL3(ReleaseByteArrayElements, jenv, $input, (jbyte *) $1, 0);
}
%typemap(javain) (unsigned char *out, unsigned long long *out_len)"$javainput"
/* Prevent default freearg typemap from being used */
%typemap(freearg) (unsigned char *out, unsigned long long *out_len)""
Generated wrapper.c (partial)
SWIGEXPORT jint JNICALL Java_com_testing_foo_jni_1foo(JNIEnv *jenv, jclass jcls, jbyteArray jarg1, jbyteArray jarg3....
.
.
.
{
arg1 = (*jenv)->GetByteArrayElements(jenv, jarg1, 0); <-- get
unsigned long long tp = (*jenv)->GetArrayLength(jenv, jarg1);
arg2 = &tp;
}
.
.
.
result = (int)foo(arg1,arg2,... <-- call foo
jresult = (jint)result;
***THESE GENERATE THE ERROR.***
{
(*jenv)->ReleaseByteArrayElements(jenv, jarg1, (jbyte *) arg1, 0); <-- release
}
{
(*jenv)->ReleaseByteArrayElements(jenv, jarg3, (jbyte *) arg3, 0);
}
{
(*jenv)->ReleaseByteArrayElements(jenv, jarg5, (jbyte *) arg5, 0);
}
.
.
.
***END SECTION***
return jresult;