Java JNI调用加载库

时间:2011-12-08 20:16:28

标签: java loadlibrary java-native-interface

如果我有两个对编译的C代码进行本机调用的Java类,并且我在另一个类中调用这两个类,它是否会影响内存?例如,我有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 个答案:

答案 0 :(得分:8)

不,没关系。在同一个类加载器中多次调用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.

答案 1 :(得分:2)

最好有使用该库的类,加载库。如果必须调用程序加载库,则可以在不加载库的情况下调用本机方法。

答案 2 :(得分:2)

Jni libs是动态库。我认为他们必须是为了被loadLibrary加载。动态库的一个优点是,如果它们已经加载到内存中,则使用该副本而不是重新加载。所以你可以使用两个loadlibrary调用。

另一个问题是如果你把loadlibrary调用放在C类中,你就破坏了其他两个类的封装。在任何大型项目中,有人最终将在a类或b类中调用其中一个本机调用而不通过类c。这样做不会那么好。

答案 3 :(得分:0)

似乎和NdkFoo类是谨慎的,并且每个方法都是本地方法。然后从A你可以使用

NdkFoo.getInstance().mathMethod();

和B可以做

NdkFoo.getInstance().nonMathMethod();

它还使得创建本机库名称与支持java类名称一致。