gpt4 book ai didi

Java - 通过相对路径加载 dll 并将它们隐藏在 jar 中

转载 作者:IT老高 更新时间:2023-10-28 20:52:31 30 4
gpt4 key购买 nike

第 1 部分

我正在开发一个应作为 jar 发布的 Java 应用程序。该程序依赖于 JNI 调用的 C++ 外部库。要加载它们,我使用带有绝对路径的方法 System.load ,这工作正常。

但是,我真的很想将它们“隐藏”在 JAR 中,所以我创建了一个包来收集它们。这迫使我加载一个相对路径——包路径。通过这种方法,我让用户可以在任何目录中运行 JAR,而不必担心链接 DLL 或厌倦以前的安装过程。

这会引发预期的异常:

Exception in thread "main" java.lang.UnsatisfiedLinkError: Expecting an absolute path of the library

我怎样才能让它工作?

第 2 部分

将 DLL 复制到文件夹的方法(如下所述)仅在我在 eclipse 环境下运行时才有效。运行导出的 JAR,DLL 二进制文件创建良好,但加载 JNI 会引发下一个异常:

Exception in thread "main" java.lang.reflect.InvocationTargetException

 at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:56)
Caused by: java.lang.UnsatisfiedLinkError: C:\Users\Supertreta\Desktop\nm files\temp\jniBin.dll: Can't find dependent libraries at java.lang.ClassLoader$NativeLibrary.load(Native Method)

我运行这个加载方法:

public static void loadBinaries(){
String os = System.getProperty("os.name").toLowerCase();

if(os.indexOf("win") >= 0){
ArrayList<String> bins = new ArrayList<String>(){{
add("/nm/metadata/bin/dependence1.dll");
add("/nm/metadata/bin/dependence2.dll");
add("/nm/metadata/bin/dependence3.dll");
add("/nm/metadata/bin/dependence4.dll");
add("/nm/metadata/bin/jniBin.dll");
}};

File f = null;
for(String bin : bins){
InputStream in = FileManager.class.getResourceAsStream(bin);
byte[] buffer = new byte[1024];
int read = -1;
try {
String[] temp = bin.split("/");
f = new File(TEMP_FOLDER, temp[temp.length-1]);
FileOutputStream fos = new FileOutputStream(f);

while((read = in.read(buffer)) != -1) {
fos.write(buffer, 0, read);
}
fos.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}

System.load(f.getAbsolutePath());
}
}

我认为这可能是访问权限问题,但不知道如何解决。你怎么看?

最佳答案

我不相信您可以直接从 JAR 加载 DLL。您必须采取将 DLL 从 JAR 中复制出来的中间步骤。下面的代码应该做到这一点:

public static void loadJarDll(String name) throws IOException {
InputStream in = MyClass.class.getResourceAsStream(name);
byte[] buffer = new byte[1024];
int read = -1;
File temp = File.createTempFile(name, "");
FileOutputStream fos = new FileOutputStream(temp);

while((read = in.read(buffer)) != -1) {
fos.write(buffer, 0, read);
}
fos.close();
in.close();

System.load(temp.getAbsolutePath());
}

关于Java - 通过相对路径加载 dll 并将它们隐藏在 jar 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4691095/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com