Я пытаюсь реализовать связывание Java / C ++ для класса потоковой передачи звука.Для простоты моего примера я приведу его метод поиска, которого достаточно для описания моей проблемы:
public abstract class JSoundStream extends SoundStream {
public abstract void seek(float timeOffset);
}
Для тестирования я использую следующую реализацию:
@Override public void seek(float timeOffset) {
System.out.println("seek(" + timeOffset + ")");
}
Метод seek
- это метод обратного вызова, делегированный родными функциями C ++, который служит в качестве обратного вызова для всего, что воспроизводит поток.Изобразите, например, приложение медиаплеера с функцией ускоренной перемотки вперед:
нажата кнопка «Перемотка вперед» -> Потоковая библиотека вызывает обратный вызов C ++ seek
-> Метод делегирования на Java seek
Обратите внимание, что это всего лишь пример, не участвует ни поток рассылки событий, ни что-либо еще в стиле фанк.
Когда создается экземпляр JSoundStream
, вызывается собственный метод, который сохранитобратно указатель Java VM (JavaVM*
), а также ссылку на объект Java (jobject
).Я делаю это потому, что не могу контролировать, когда именно вызывается обратный вызов, и я не знаю способа получить среду JNI или объект live без ссылок на Java вообще.Поэтому я сохраняю эту информацию во время создания объекта, где у меня есть ссылки.
Внутри метода C ++ seek
я пытаюсь вызвать метод Java seek
следующим образом:
virtual void OnSeek(float timeOffset) {
JNIEnv* env;
jvm->AttachCurrentThread((void**)&env, NULL);
env->CallVoidMethod(binding, m_seek, (jfloat)timeOffset);
}
Где binding
- это jobject
, jvm
указатель Java VM и m_seek
jmethodID
seek
метода, который я получил ранее.
Однако этот вызов CallVoidMethod
приведет к нарушению доступа в jvm.dll
.Все указатели и значения действительны для того, что я могу сказать, и я убедился, что объект Java не получает мусор.Я считаю, что хранение jobject
и / или указателя Java VM является источником проблемы, но опять же я не могу понять, почему, поскольку эти значения не меняются во время работы программы.
Может кто-нибудьувидеть проблему в том, как я подхожу к этому?Как иначе - без сохранения ссылок - я бы вызвал объектный метод Java из кода C ++?