简体   繁体   English

Java JNI调用加载库

[英]Java JNI call to load library

Does it impact memory if I have two Java classes that have native calls to compiled C code and I call both those classes in another class? 如果我有两个对编译的C代码进行本机调用的Java类并且我在另一个类中调用这两个类,它会影响内存吗? For instance I have Class A and Class B with both calls to native functions. 例如,我有A类和B类,同时调用本机函数。 They are setup like this: 它们的设置如下:

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;
    }
}

Class C then calls both, since they both make a static call to load the library will that matter in class C? C类然后调用两个,因为它们都进行静态调用来加载库在C类中是否重要? Or is it better to have Class C call System.loadLibrary(...? 或者让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();

    }
}

No, it doesn't matter. 不,没关系。 It's harmless to call loadLibrary() more than once in the same classloader. 在同一个类加载器中多次调用loadLibrary()是无害的。

From the documentation for Runtime.loadLibrary(String) , which is called by System.loadLibrary(String): 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.

Its better to have the class which uses the library, load the library. 最好有使用库的类,加载库。 If you have to caller load the library you make it possible to call the native methods without loading the library. 如果必须调用程序加载库,则可以在不加载库的情况下调用本机方法。

Jni libs are dynamic libs. Jni libs是动态库。 I'd think they'd have to be in order to be loaded by loadLibrary. 我认为他们必须是为了被loadLibrary加载。 One of the advantages of dynamic libraries is that if they are already loaded into memory, that copy gets used instead of being reloaded. 动态库的一个优点是,如果它们已经加载到内存中,则使用该副本而不是重新加载。 So you can use the two loadlibrary calls. 所以你可以使用两个loadlibrary调用。

The other issue is that if you put the loadlibrary call in class C, you've ruined the encapsulation of the other two classes. 另一个问题是如果你把loadlibrary调用放在C类中,你就破坏了其他两个类的封装。 In any large project, someone is eventually going to call one of the native calls in class a or class b without going through class c. 在任何大型项目中,有人最终将在a类或b类中调用其中一个本机调用而不通过类c。 That will not work so well. 那不会那么好用。

Seems like and NdkFoo class would be prudent, and have every method be a native one. 似乎和NdkFoo类一样谨慎,并且每个方法都是本地方法。 Then from A you could use 然后从A你可以使用

NdkFoo.getInstance().mathMethod();

and B could do 和B可以做到

NdkFoo.getInstance().nonMathMethod();

It also makes creating the native library name consistent with the backing java class name. 它还使创建本机库名称与后备java类名称一致。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM