Код Android JNI C++ всегда получает "одно и то же" значение для задания для двух разных объектов SurfaceView
В Android код JAVA:
public native int addRenderer(int channel, Object glSurface);
Context context = getApplicationContext();
SurfaceView svRemotePartyA = new SurfaceView(context);
SurfaceView svRemotePartyB = new SurfaceView(context);
addRenderer(0, svRemotePartyA);
addRenderer(1, svRemotePartyB);
В коде Android JNI C++:
extern "C" jint JNIEXPORT JNICALL Java_addRenderer(
JNIEnv* jni,
jobject j_vie,
jint channel,
jobject surface) {
LOG(LS_INFO) << "Java_addRenderer(): surface=" << surface;
// some processing
}
Когда я запускаю программу, я всегда читаю следующий журнал! оба объекта SurfaceView имеют одинаковое значение в выводе журнала кода JNI C++:
(render_manager.cc:175): Java_addRenderer(): surface==0xbeed6120
(render_manager.cc:175): Java_addRenderer(): surface==0xbeed6120
В чем проблема?
2 ответа
Вы смотрите на локальные ссылки, которые никогда не должны использоваться вне контекста того же метода JNI. Если вы получите глобальную ссылку для этого рабочего места, вы получите 2 разных.
Вы не должны пытаться связать значение с конкретным битовым шаблоном ссылки JNI.
Например, в Dalvik локальные ссылки - это просто индексы в таблице в стеке. Если вы делаете один и тот же вызов несколько раз с разными объектами, вы будете каждый раз видеть одно и то же "значение" для ссылки, потому что ссылка на объект находится в одном и том же месте в локальной таблице ссылок.
(Это не так просто - Дальвик фактически ввел в ссылку тривиальный серийный номер, чтобы было проще определить, когда использовался локальный номер ссылки после его восстановления - но вы поняли идею.)
Точно так же вы не можете делать предположения о глобальных ссылках. Если вы создадите две глобальные ссылки на один и тот же объект, очень вероятно, что эти ссылки будут иметь разные 32-битные значения.
Каждая ВМ отличается. Старые (до ICS) версии Dalvik фактически передавали необработанные указатели, и вы могли сравнить эталонные значения, чтобы определить, были ли два объекта одинаковыми. Переход к косвенным ссылкам потребовал исправления нескольких вещей.
Если вы хотите сказать, являются ли два объекта одинаковыми, вам нужно иметь ссылки на оба и использовать JNI IsSameObject()
функция.
Некоторый дополнительный фон здесь.