2017-01-08 4 views
-1

, известно, что функция JNI обычно называют следующим образом (из документации Oracle):вызова JNI функции из-за пределов соответствующего класса Java

Dynamic linkers resolve entries based on their names. A native method name is concatenated from the following components:

  • the prefix Java_
  • a mangled fully-qualified class name
  • an underscore (“_”) separator
  • a mangled method name

Так имя метода всегда должен содержать соответствующий Java имя класса и не могут быть вызваны извне этого класса. В случае u're называют этот метод из другого класса Android студии инспектор дает предупреждение, как это:

Reports native method declarations in Java where no corresponding JNI function is found in the project.

А если и работать, что и получит java.lang.UnsatisfiedLinkError: Native метод не нашел исключение.

И, таким образом, мой вопрос: как создать общую библиотеку с собственными функциями, которую можно было бы назвать от любым Java-классом?

Чтобы быть более конкретным. У меня есть Java-класс MyActivity. И мне нужно вызвать некоторую функцию jni из этого класса. Как я понимаю, согласно документу Oracle, эту функцию следует называть smth, как Java_xxx_yyy_zz_MyActivity_func1. Тогда представьте, что я также хочу назвать эту функцию из другого приложения для Android. Я скопирую папку lib * .so в папку libs, но я не смогу вызвать функцию func1, а родная функция coz не будет найдена. Для возможности использования этой функции в новом приложении мне нужно создать иерархию папок, которая представляет собой xxx/yyy/zzz и класс MyActivity, и после этого я смогу вызвать func1, но только из этого класса MyActivity. Но что мне делать, если я хочу называть это другим классом?

+0

«Нельзя назвать из-за пределов класса »- это BS, и поэтому поэтому вы сделаете выводы из этого. Сообщение об ошибке, которое вы указываете, относится к случаю * получения неправильного имени JNI *, что является совершенно другой вещью от вызова из-за пределов класса. Неясно, что вы спрашиваете. – EJP

+0

@EJP i обновленный вопрос – borune

ответ

1

- новый ответ, данный вопрос редактирует -

Спасибо за разъяснение. AFAIK, нет automatic способ связать один и тот же собственный метод с несколькими методами Java. Тем не менее, есть несколько способов, которые могут вам пригодиться:

(1) Позвоните на общий фасад. Предполагая, что вы не должны передать экземпляр объекта Java для метода, первый объявить класс фасад, как в моем оригинальный ответ, и реализовать его в C:

public class JniStuff { 
    public static native void method1(String s, int i); 
} 

JNIEXPORT void JNICALL Java_net_redpoint_scratch_JniStuff_method1 
     (JNIEnv *, jclass, jstring, jint); 

затем вызвать его из любого другого класса, который вы хотите:

public class MyClass { 
    public static void method1(String s, int i) { 
     JniStuff.method1(s, i); 
    } 
} 

(2) Используйте RegisterNatives позвонить, чтобы связать один метод C с несколькими методами Java, как объяснено here. Однако я сомневаюсь, что вы найдете это удобным, поскольку регистрация должна быть выполнена с «C», так что вам также понадобится какой-то метод запуска, который вызывается первым для этого.

--- старый ответ -

Я не уверен, что вы после этого, точно.Если ваша проблема в том, что вы не хотите, чтобы создать объект, содержащий методы, объявите их статическими:

package net.redpoint.scratch; 
public class JniStuff { 
    public static native void method1(String s, int i); 
} 

javah генерирует этот нативный метод подписи:

JNIEXPORT void JNICALL Java_net_redpoint_scratch_JniStuff_method1 
     (JNIEnv *, jclass, jstring, jint); 

Ваш другой код Java является звоните:

JniStuff.method1("something", 123); 

без создания экземпляра объекта типа JniStuff