多参数类型映射和包装指针

时间:2016-03-08 05:16:35

标签: java c java-native-interface swig

我在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;

0 个答案:

没有答案