Java 使用变量加载库

Java load library with variable

我正在尝试使用 System.load() 函数和变量加载库。 当我在每个函数中加载库时它会起作用,但我希望能够通过一个通用系统加载来完成它,类似于您在使用已知库路径加载时所做的事情。

    static{
           System.load("/libraryPath/libLibrary.so");
    }

但是,无法为此 System.load 提供静态变量,因为它不会在调用加载时实例化。 有任何想法吗? 谢谢

编辑

我找到了解决办法, 我最终在不同的 class 中使用了静态 getter。 这样做的好处是我可以解析存储位置的配置文件。存储变量,并在 class 中使用静态方法检索它,我需要该库。现在我可以像这样进行一般加载:

    static{
        System.load(OtherClass.getLibrary());
    }

感谢大家的帮助

静态代码按照声明的顺序执行,因此您需要在静态代码块之前声明变量。这就是为什么静态代码块经常有问题,最好用不同的形式替换。

如果我理解得很好,你希望确保对

的调用
System.load("/libraryPath/libLibrary.so");

在代码的不同部分使用它之前已经完成。

如果您创建一个 class 来执行以下操作,您应该获得它。

public class Loader {
    static {
        System.load("/libraryPath/libLibrary.so");
    }

    public static void init() {
    }
}

并在使用库之前编写代码:

Loader.init();
// Code using native library

这将确保该库只加载一次,但您也可以确定它在使用前已经加载过。

方法init() 是确保class 加载程序有效加载到内存中的技巧。仅有的 import 语句不足以确保 static init 将被执行。

这是我在任何地方都用来加载本机代码的代码。 希望对你有所帮助。

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class NativeLoader {

/** Directory containing native libraries */
private static final String NATIVE_LIBS_DIRECTORY = "/native/"; 

/** Extension for temporary file containing extracted native library */
private static final String TEMPORARY_FILE_EXT = ".tmp"; 

    /**
     * Loads a native library
     *  
     * @param libraryName
     *            name of the native library to load
     * @throws IOException
     *             if the native library cannot be loaded
     */
    public static void loadEmbeddedLibrary(String libraryName) throws IOException {

        String mapName = System.mapLibraryName(libraryName);
        InputStream is = NativeLoader.class.getResourceAsStream(NATIVE_LIBS_DIRECTORY + mapName);

        if (is != null) {
            File native_library = File.createTempFile(mapName, TEMPORARY_FILE_EXT);
            native_library.deleteOnExit();
            native_library.setWritable(true);
            native_library.setExecutable(true);

            if (native_library.exists()) {
                FileOutputStream os = new FileOutputStream(native_library);
                int read;
                byte[] buffer = new byte[4096];
                while ((read = is.read(buffer)) != -1) {
                    os.write(buffer, 0, read);
                }
                os.close();
                is.close();

                System.load(native_library.getPath());
            }
            else {
                is.close();
            }
        }
    }
}