Java 和 JNI - 加载 dll 库仅适用于我的计算机

标签 java dll load java-native-interface

我在通过 JNI 让我的 java 应用程序与外部 c++ dll 一起工作时遇到了一些烦人的问题。这些库位于包内。当我需要将它们加载到虚拟机中时,我将它们复制到临时文件夹中。接下来是 dll:

libcurld.dll; libfftw3f-3.dll; libmad.dll; libsamplerate.dll; main.dll;

main.dll是实现java端声明的native方法的。这个dll依赖上面的才能正常运行。我只在 Visual Studio 上编译了 main.ddl,一个二进制文件用于 7 个其他用于 xp 的二进制文件。其他的已下载并简单链接。我运行下一个方法来在 java 上加载库:

public static boolean loadBinaries(){
    String os = System.getProperty("os.name").toLowerCase();
    ArrayList<String> bins = new ArrayList<String>();

    if(os.indexOf("windows 7") >= 0){
        bins.add("/nm/metadata/bin/win/libcurld.dll");
        bins.add("/nm/metadata/bin/win/libfftw3f-3.dll");
        bins.add("/nm/metadata/bin/win/libmad.dll");
        bins.add("/nm/metadata/bin/win/libsamplerate.dll");
        bins.add("/nm/metadata/bin/win/seven/main.dll");
    }
    else if(os.indexOf("windows xp") >= 0){
        bins.add("/nm/metadata/bin/win/libcurld.dll");
        bins.add("/nm/metadata/bin/win/libfftw3f-3.dll");
        bins.add("/nm/metadata/bin/win/libmad.dll");
        bins.add("/nm/metadata/bin/win/libsamplerate.dll");
        bins.add("/nm/metadata/bin/win/xp/main.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]);
            File realF = new File(f.getAbsolutePath());
            if(realF.exists())
                f.delete();

            FileOutputStream fos = new FileOutputStream(realF);

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

            System.load(f.getAbsolutePath());
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    return true;
}

可执行 jar 在我的机器上总是完美运行,但在其他机器上则不然......我从测试中得到了下一个错误:

(xp)
Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\temp\main.dll: Can't find dependent libraries at java.lang.ClassLoader$NativeLibrary.load(Native Method)...

(seven)
C:\temp\main.dll: The application has failed to start because its side-by-side configuration is incorrect...

所有 dll 都在临时文件夹中编写得很好,正如我所说,这在我的计算机上运行良好。我以为这可能是因为在 VS 上以 Debug模式编译。不幸的是,将其转为发布版并没有改变任何东西,除非返回较小的二进制文件。

这可能是什么? Visual Studio 上是否缺少某些配置详细信息? 提前致谢。

最佳答案

首先,我将复制所有 DLL,然后在两个循环中加载它们。

其次,从错误消息来看,似乎还有一个 main.dll 需要的 DLL 在其他计算机上不存在。 可能是 C++ 运行时库通常未安装在您需要的版本中,这就是许多游戏或其他应用程序首先安装这些库的原因。

关于Java 和 JNI - 加载 dll 库仅适用于我的计算机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4737085/

相关文章:

java - 如果禁用日志级别,如何防止日志消息中的字符串生成器

java - 将 Jaxb Pojos 序列化到多个或不同的命名空间

c++ - 在 Delphi 的 c++ dll 中使用数组参数调用函数

c# - 如何确定用户控件何时完全加载并显示?

java - 使用 JXL-Selenium(Java) 将数据写入 Excel

java - JPA 实体何时以及为什么应该实现 Serializable 接口(interface)?

.net - 可以从 .net 调用的非常简单的 C++ DLL

c++ - 编译器如何处理外部变量

c# - 使用 Windows.Storage 命名空间时出错

css - 如何预加载 css :hover background images