Вызов Java JNI для загрузки библиотеки - PullRequest
8 голосов
/ 09 декабря 2011

Влияет ли это на память, если у меня есть два Java-класса, которые имеют собственные вызовы скомпилированного кода C, и я вызываю оба этих класса в другом классе?Например, у меня есть класс A и класс B с обоими вызовами собственных функций.Они настроены так:

public class A{
    // declare the native code function - must match ndkfoo.c
    static {
        System.loadLibrary("ndkfoo");
    }

    private static native double mathMethod();

    public A() {}

    public double getMath() {
          double dResult = 0;  
          dResult = mathMethod();
          return dResult;
    }
}


public class B{
    // declare the native code function - must match ndkfoo.c
    static {
        System.loadLibrary("ndkfoo");
    }

    private static native double nonMathMethod();

    public B() {}

    public double getNonMath() {
          double dResult = 0;  
          dResult = nonMathMethod();
          return dResult;
    }
}

Затем класс C вызывает оба, поскольку они оба делают статический вызов для загрузки библиотеки, будет ли это иметь значение в классе C?Или лучше, чтобы класс C вызывал System.loadLibrary (...?

public class C{
    // declare the native code function - must match ndkfoo.c
    //  So is it beter to declare loadLibrary here than in each individual class?
    //static {
    //  System.loadLibrary("ndkfoo");
    //}
    //

    public C() {}

    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        double result = a.getMath() + b.getNonMath();

    }
}

Ответы [ 4 ]

8 голосов
/ 09 декабря 2011

Нет, это не имеет значения. Вызывать loadLibrary () более одного раза в одном загрузчике классов безопасно.

Из документации для Runtime.loadLibrary (String) , которая вызывается System.loadLibrary (String):

   If this method is called more than once with the same library name, 
   the second and subsequent calls are ignored.
2 голосов
/ 09 декабря 2011

Jni libs - динамические libs.Я думаю, что они должны быть загружены loadLibrary.Одним из преимуществ динамических библиотек является то, что если они уже загружены в память, эта копия используется вместо перезагрузки.Таким образом, вы можете использовать два вызова loadlibrary.

Другая проблема заключается в том, что если вы поместите вызов loadlibrary в класс C, вы разрушите инкапсуляцию двух других классов.В любом крупном проекте кто-то в конечном итоге собирается вызвать один из собственных вызовов в классе a или классе b, не проходя класс c.Это не будет работать так хорошо.

2 голосов
/ 09 декабря 2011

Лучше иметь класс, который использует библиотеку, загрузить библиотеку.Если вам нужно загрузить библиотеку, вы можете вызывать нативные методы без загрузки библиотеки.

0 голосов
/ 09 декабря 2011

Похоже, и NdkFoo класс будет разумным, и каждый метод должен быть нативным.Тогда из A вы можете использовать

NdkFoo.getInstance().mathMethod();

, а B может сделать

NdkFoo.getInstance().nonMathMethod();

Это также делает создание собственного имени библиотеки совместимым с именем вспомогательного java-класса.

...