Динамический вызов нативного метода в Java

1

Я делаю программное обеспечение (для Android) для считывания значений счетчиков с датчиков. Ожидается, что программное обеспечение будет получать обновления очень часто, чтобы поддерживать большее количество датчиков. Функциональность для считывания данных счетчиков для этих датчиков реализована в собственных библиотеках, загружаемых приложением в приложении.

У меня есть список общих объектов и функция ввода, которая должна быть вызвана (возвращаемое значение сохраняется):

libprintf.so,hookPrintf
libharx.so,hookHarx

Каждая библиотека загружается во время выполнения: System.loadLibrary("printf");

Подпись каждой функции будет выглядеть так:

public native int hookPrintf();
public native int hookHarx();

Проблема в том, что я не знаю заранее (во время компиляции), какие общие объекты должны быть загружены, и поэтому я не могу добавить эти подписи в источник java.

Я попытался использовать Reflection для динамического вызова методов следующим образом:

Method entryMethod = Expat.class.getMethod(hookMethod);
Object test = entryMethod.invoke(this);
System.out.writeln(test.toString());

Однако, если подпись отсутствует, это будет по-прежнему терпеть неудачу с исключением NoSuchMethodException. Есть ли другой способ, чтобы иметь возможность называть собственные методы, не требуя, чтобы они определялись заранее?

Изменение: используя функцию RegisterNatives, я могу динамически регистрировать свои функции из общего объекта, но для этого все еще требуется, чтобы подпись метода определялась в классе. Что делает метод registerNatives()?

Теги:
jni

2 ответа

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

Вероятно, вы можете иметь класс Java только с двумя собственными методами и полагаться на RegisterNatives и UnregisterNatives и переключать загруженные собственные реализации во время выполнения. При этом я предпочел бы использовать собственную библиотеку-оболочку с собственными методами

private static native void hook(String libName, String hookName);

Эта оболочка будет использовать dlopen() или LoadLibraryEx(), а также, при необходимости, выгружать внешние библиотеки.

В некоторых JVM вы можете динамически создавать новые классы, но это довольно сложно.

  • 0
    Спасибо за предложение UnregisterNatives путем переключения реализаций. Я пойду с этим. Я верю, что подпись вашего метода должна включать ключевое слово native .
  • 0
    Спасибо, родных не хватало
1

У вас есть фундаментальная проблема дизайна. Я бы предложил вернуться и создать JNI-библиотеку, которая реализует один метод, такой как public native int createHook() или что-то подобное. Затем сделайте выбор в своем родном коде на основе некоторого условного. Если вам все еще нужно/нужно загружать библиотеки во время выполнения, создайте библиотеки non-jni для libprintf.so и libharx.so и используйте либо dlopen для динамической загрузки библиотеки, либо слабо свяжите библиотеки с библиотекой jni.

  • 0
    Я обновил вопрос с моим конкретным вариантом использования. Это определенно возможно, я думаю, я просто надеялся, что это будет проще, и Java подхватит функции, зарегистрированные через JNI. Прямо сейчас я имею дело с этим, создавая заглушку, которая содержит hookLib1 () до hookLib1000 () для поддержки обновлений на будущий год, что далеко не идеально.

Ещё вопросы

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