JNI - Могу ли я использовать RegisterNatives без вызова System.loadLibrary для собственных плагинов?

0

У меня есть приложение C++, которое использует плагины (он динамически загружает определенные файлы с общим lib). У меня возникли проблемы с пониманием того, что мне нужно сделать, чтобы вызвать динамически загруженный собственный код с Java.

Должен ли я использовать System.loadLibrary/System.load для "предварительной загрузки" собственных общих объектов ("плагинов"), чтобы иметь возможность звонить в этот собственный код? Или я буду в порядке, только вызываю RegisterNatives из плагина после загрузки его в свой собственный код? Я уже назвал System.loadLibrary для моего основного родного приложения lib - его последующие плагины загружают родные библиотеки lib, на которые стоит этот вопрос.

И если мне удастся избежать вызова RegisterNatives, что произойдет, если я вдруг решит выгрузить плагин, и JVM попытается вызвать собственный метод, который был внутри него?

Теги:
jni

1 ответ

0
Лучший ответ

По крайней мере, Android VM требует, чтобы все собственные методы были "зарегистрированы" при создании экземпляра класса. Вот почему System.load() обычно вызывается в статическом конструкторе, а не позже.

Два способа разрешить собственные методы - через RegisterNatives() в JNI_OnLoad() или хотя совпадение имен (C экспортирует имена функций, как сообщается javah).

Вы можете искать указатели на функции для RegisterNatives() во всех загруженных модулях или загружать больше модулей и получать от них указатели. RegisterNatives() может быть вызван в любое время, и если вы действительно хотите выгрузить некоторые плагины, вы можете использовать UnregisterNatives().

Последний был введен для поддержки следующего потока (псевдокод следует):

SwitchPlugin() {
    UnregisterNatives();
    unloadPlugin(oldHandle);
    newHandle = loadPlugin(newPluginName);
    RegisterNatives();
}

Ваше приложение, вероятно, потерпит неудачу, если попытается использовать собственный метод, который реализуется в незагруженном плагине или после того, как он будет незарегистрирован с помощью UnregisterNatives().

  • 0
    Я не верю, что первоначальное предложение верно, как если бы оно было, объявление родного метода и загрузка реализации позже (но перед использованием) не сработало бы. На самом деле это происходит, и если загрузка пропускается, исключение времени выполнения возникает только тогда, когда выполняется попытка использовать отсутствующий метод, а не когда создается экземпляр класса, членом которого он является.
  • 0
    @ Крис-Страттон: вы говорите о реализации Android?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню