跨C++;和Java使用控制器 我有一个C++程序,从网络接收二进制数据。在接收到数据之后,它将将数据从C++返回到java客户端。我使用SWIG中的Dead特性,可以轻松地跨C++和java实现跨语言多态性,以进行回调。给你 但是我发现在C++中,从char *中的chip没有类型映射到java中的字节[]。所以,我给病毒添加了一个补丁。给你

跨C++;和Java使用控制器 我有一个C++程序,从网络接收二进制数据。在接收到数据之后,它将将数据从C++返回到java客户端。我使用SWIG中的Dead特性,可以轻松地跨C++和java实现跨语言多态性,以进行回调。给你 但是我发现在C++中,从char *中的chip没有类型映射到java中的字节[]。所以,我给病毒添加了一个补丁。给你,java,c++,callback,swig,Java,C++,Callback,Swig,比如说。我有一个C++类,叫做a:< /p> class A{ public: virtual void onDataReceived(const char* BYTE, const size_t len) {} }; 然后在Java代码中,我有另一个类B来扩展A: class B extends A { @Override public void onDataReceived(byte[] data, long len) { //handling

比如说。我有一个C++类,叫做a:< /p>
class A{
public:
       virtual void onDataReceived(const char* BYTE, const size_t len) {}
};
然后在Java代码中,我有另一个类B来扩展A:

class B extends A {
    @Override
    public void onDataReceived(byte[] data, long len) {
       //handling the data.
    }
}
我可以在Java代码中接收字节数组,但JVM似乎从未对其进行垃圾收集。SWIG生成的包装文件中的onDataReceived方法如下所示:

void SwigDirector_A::onDataReceived(char const *BYTE, size_t const len) {
  JNIEnvWrapper swigjnienv(this);
  JNIEnv * jenv = swigjnienv.getJNIEnv();
  jobject swigjobj = (jobject) NULL;
  jbyteArray jBYTE = 0;
  jlong jlen;

  if (!swig_override[3]) {
    A::onDataReceived(BYTE,len);
    return;
  }
  swigjobj = swig_get_self(jenv);
  if (swigjobj && jenv->IsSameObject(swigjobj, NULL) == JNI_FALSE) {
    {
      jbyteArray jb = (jenv)->NewByteArray(strlen(BYTE));
      (jenv)->SetByteArrayRegion(jb, 0, strlen(BYTE), (jbyte*)BYTE);
      jBYTE = jb;
    }
    jlen = (jlong) len;
    jenv->CallStaticVoidMethod(Swig::jclass_DataTransferJNI, Swig::director_methids[3], swigjobj, jBYTE, jlen);
    if (jenv->ExceptionCheck() == JNI_TRUE) return;
  } else {
    SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null upcall object");
  }
  if (swigjobj) jenv->DeleteLocalRef(swigjobj);
}
<>我的C++代码,在回调完成后,我将删除接收缓冲区中的数据。但是我从JavaVisualVM检查,Java客户机进程使用的内存在很长一段时间后没有被GC调用。谢谢你的帮助


PS.数据非常大,大约32KB。

我通过删除Director typemaps中对jb的引用来解决这个问题:(jenv)->DeleteLocalRef(jb)


这是一个问题。

我通过在directortypemaps中删除对jb的引用得到了解决:(jenv)->DeleteLocalRef(jb);你应该把它写下来作为答案,然后把它标记为接受。这个解决方案太重要了,不能仅仅作为一个评论。
void SwigDirector_A::onDataReceived(char const *BYTE, size_t const len) {
  JNIEnvWrapper swigjnienv(this);
  JNIEnv * jenv = swigjnienv.getJNIEnv();
  jobject swigjobj = (jobject) NULL;
  jbyteArray jBYTE = 0;
  jlong jlen;

  if (!swig_override[3]) {
    A::onDataReceived(BYTE,len);
    return;
  }
  swigjobj = swig_get_self(jenv);
  if (swigjobj && jenv->IsSameObject(swigjobj, NULL) == JNI_FALSE) {
    {
      jbyteArray jb = (jenv)->NewByteArray(strlen(BYTE));
      (jenv)->SetByteArrayRegion(jb, 0, strlen(BYTE), (jbyte*)BYTE);
      jBYTE = jb;
    }
    jlen = (jlong) len;
    jenv->CallStaticVoidMethod(Swig::jclass_DataTransferJNI, Swig::director_methids[3], swigjobj, jBYTE, jlen);
    if (jenv->ExceptionCheck() == JNI_TRUE) return;
  } else {
    SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null upcall object");
  }
  if (swigjobj) jenv->DeleteLocalRef(swigjobj);
}