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();
}
}
}
}
我正在尝试使用 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();
}
}
}
}