У меня есть приложение C++, которое использует плагины (он динамически загружает определенные файлы с общим lib). У меня возникли проблемы с пониманием того, что мне нужно сделать, чтобы вызвать динамически загруженный собственный код с Java.
Должен ли я использовать System.loadLibrary/System.load для "предварительной загрузки" собственных общих объектов ("плагинов"), чтобы иметь возможность звонить в этот собственный код? Или я буду в порядке, только вызываю RegisterNatives из плагина после загрузки его в свой собственный код? Я уже назвал System.loadLibrary для моего основного родного приложения lib - его последующие плагины загружают родные библиотеки lib, на которые стоит этот вопрос.
И если мне удастся избежать вызова RegisterNatives, что произойдет, если я вдруг решит выгрузить плагин, и JVM попытается вызвать собственный метод, который был внутри него?
По крайней мере, Android VM требует, чтобы все собственные методы были "зарегистрированы" при создании экземпляра класса. Вот почему System.load()
обычно вызывается в статическом конструкторе, а не позже.
Два способа разрешить собственные методы - через RegisterNatives()
в JNI_OnLoad()
или хотя совпадение имен (C экспортирует имена функций, как сообщается javah
).
Вы можете искать указатели на функции для RegisterNatives()
во всех загруженных модулях или загружать больше модулей и получать от них указатели. RegisterNatives()
может быть вызван в любое время, и если вы действительно хотите выгрузить некоторые плагины, вы можете использовать UnregisterNatives()
.
Последний был введен для поддержки следующего потока (псевдокод следует):
SwitchPlugin() {
UnregisterNatives();
unloadPlugin(oldHandle);
newHandle = loadPlugin(newPluginName);
RegisterNatives();
}
Ваше приложение, вероятно, потерпит неудачу, если попытается использовать собственный метод, который реализуется в незагруженном плагине или после того, как он будет незарегистрирован с помощью UnregisterNatives()
.