У меня есть программа на C ++ для получения двоичных данных из сети.После получения данных они будут вызывать данные в виде байтового массива из C ++ для клиента Java.Я использую функцию директора в SWIG, чтобы легко достичь межязыкового полиморфизма в C ++ и Java для обратного вызова.Вот ссылка .
Но я обнаружил, что в SWIG нет типографских карт от char * в C ++ до byte [] в Java.Итак, я добавил патч к virous.i.Вот ссылка .
/*Director specific typemaps*/
%typemap(directorin, descriptor="[B") char *BYTE {
jbyteArray jb = (jenv)->NewByteArray(strlen(BYTE));
(jenv)->SetByteArrayRegion(jb, 0, strlen(BYTE), (jbyte*)BYTE);
$input = jb;
}
%typemap(directorout) char *BYTE {
$1 = 0;
if($input){
$result = (char *) jenv->GetByteArrayElements($input, 0);
if(!$1)
return $null;
jenv->ReleaseByteArrayElements($input, $result, 0);
}
}
%typemap(javadirectorin) char *BYTE "$jniinput"
%typemap(javadirectorout) char *BYTE "$javacall"
Например.У меня есть класс в C ++ с именем A:
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 никогда не собирает мусор.Метод onDataReceived в сгенерированном SWIG-файле оболочки выглядит следующим образом:
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 ++ я буду удалять данные в приемном буфере после завершения обратного вызова.Но я проверил из Java VisualVM, что память, используемая клиентским процессом java, не GC-ed через долгое время.Заранее спасибо за любую помощь!
PS.Данные довольно большие, они составляют около 32 КБ.