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

发布于 2024-10-12 12:04:55 字数 2542 浏览 2 评论 0原文

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

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

main.dll 是实现在 java 端声明的本机方法的文件。这个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 上以调试模式编译。不幸的是,将其转为发布并没有改变任何东西,除非返回较小的二进制文件。

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

I'm facing some annoying problems to get my java application working with external c++ dlls, through JNI. The libraries are located inside packages. I copy them to a temporary folder when I need to load them into virtual machine. The dlls are the next:

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

The main.dll is the one that implements the native method declared on the java side. This dll depends on the above to run properly. I only compiled the main.ddl on visual studio, one binary for 7 other for xp. The others were downloaded and simply linked. I run the next method to load the libraries on 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;
}

The executable jar works always perfectly on my machine, but not in others... I got the next errors from my tests:

(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...

All the dlls are well written in the temp folder and, as I said, this works well in my computer. I had thought this could be because compiling in debug mode on VS. Unfortunately, turning it to release didn't change anything, unless returning smaller binaries.

What can this be? Is some configuration detail missing on visual studio?
Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

江南月 2024-10-19 12:04:55

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

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

First, I would copy all DLLs and then load them in two loops.

Second, from the error message it seems that there is yet another DLL that main.dll requires that is not present on the other machines.
It might be the C++ runtime libraries what often not installed in the version you need, which is why many games or other apps install those first.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文