Java JNI 依赖库

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1087054/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:28:48  来源:igfitidea点击:

JNI dependent libraries

javajava-native-interface

提问by Jeff Storey

I'm running a library via JNI (I didn't write it), and internally it calls another DLL. I get an error saying "Can't find dependent libraries" unless I put the path of the other DLL on the system PATH variable (I'm on Windows XP). I'd like to be able to handle this on the java command line, and I've already tried adding it to -Djava.library.path and to the classpath, neither which worked (I expected -Djava.library.path to work but not classpath, but neither worked). Is there a way to do this?

我正在通过 JNI 运行一个库(我没有编写它),并在内部调用另一个 DLL。除非我将其他 DLL 的路径放在系统 PATH 变量上(我使用的是 Windows XP),否则我会收到一条错误消息,提示“找不到相关库”。我希望能够在 java 命令行上处理这个问题,并且我已经尝试将它添加到 -Djava.library.path 和类路径,但都没有工作(我希望 -Djava.library.path 工作但不是类路径,但都不起作用)。有没有办法做到这一点?

thanks,

谢谢,

Jeff

杰夫

采纳答案by Vivek

  • If you have a DLL name 'MyNativeDLL.dll' then you should use 'MyNativeDLL' in your LoadLibrary call.
  • Use Dependency Walkerto check if there are any files required by MyNativeDLL.dll
  • If there are, include them in the same folder as MyNativeDLL.dll - one you get it working try putting the additional required files in System32 folder.
  • 如果您有一个 DLL 名称“MyNativeDLL.dll”,那么您应该在 LoadLibrary 调用中使用“MyNativeDLL”。
  • 使用Dependency Walker检查是否有 MyNativeDLL.dll 需要的文件
  • 如果有,请将它们包含在与 MyNativeDLL.dll 相同的文件夹中 - 您可以尝试将其他所需文件放在 System32 文件夹中。

回答by Liron Yahdav

I was able to get this to work without putting any DLLs on the PATH by using System.load() on all DLLs in reverse dependency order. Just to be clear, I was calling System.load() on all dependent DLLs, not just JNI DLLs. You don't have to call System.load() on DLLs that come with Windows (they're on the PATH).

通过在所有 DLL 上以反向依赖顺序使用 System.load(),我能够在不将任何 DLL 放在 PATH 上的情况下使其工作。为了清楚起见,我在所有依赖的 DLL 上调用 System.load(),而不仅仅是 JNI DLL。您不必对 Windows 附带的 DLL(它们在 PATH 上)调用 System.load()。

I was doing this in a web app where a jar included DLLs that were getting unpacked. Your situation seems simpler, so I believe it should work. I generally followed the solution here: How to make a JAR file that includes DLL files?

我在一个 Web 应用程序中执行此操作,其中一个 jar 包含正在解压缩的 DLL。你的情况似乎更简单,所以我相信它应该有效。我通常遵循这里的解决方案:如何制作包含 DLL 文件的 JAR 文件?

回答by gibbss

I've successfully injected a folder into the PATH variable using JNA. This can be used as a workaround if you want to deploy your dependent DLLs alongside your application without tainting the global environment or messing with explicit DLL load order.

我已经使用 JNA 成功地将一个文件夹注入到 PATH 变量中。如果您想将依赖 DLL 与应用程序一起部署而不污染全局环境或弄乱显式 DLL 加载顺序,则可以将其用作解决方法。

However it's not clear to me how the classloader lifecycle affects this. I've only tried this technique under the NetBeans module system, but if you look through the ClassLoader class code for loadLibrary, you'll see that it caches some path variables. It may or may not be necessary to create a new classloader to load the library on.

然而,我不清楚类加载器生命周期如何影响这一点。我只在 NetBeans 模块系统下尝试过这种技术,但是如果您查看 loadLibrary 的 ClassLoader 类代码,您会看到它缓存了一些路径变量。可能需要也可能不需要创建一个新的类加载器来加载库。

The downside is you need to use JNA or JNI. Also, it seems like a pretty gross hack. See herefor an example of how to set an environment variable using JNA.

缺点是您需要使用 JNA 或 JNI。此外,这似乎是一个非常严重的黑客攻击。有关如何使用 JNA 设置环境变量的示例,请参见此处

回答by user3448399

This helped me a lot. Also managed loading a JNI dll built using cygwin:

这对我帮助很大。还管理加载使用 cygwin 构建的 JNI dll:

first:

第一的:

/* conditioned if OS is windows because also need it to work in Linux env. */ 
System.loadLibrary("cygwin1"); 

then:

然后:

System.loadLibrary("mylib"); 

On windows, This requires either setting the java.library.path to match both libraries locations.

在 Windows 上,这需要设置 java.library.path 以匹配两个库位置。

If runnning from Eclipse, this setting may be replaced by "Native Libraries Location" in java build path (in JRE libraries settings).

如果从 Eclipse 运行,此设置可能会替换为 java 构建路径中的“本机库位置”(在 JRE 库设置中)。

However, still finding this a bit tricky.

但是,仍然觉得这有点棘手。

回答by Caesar

For me, making a static build worked, which compiles with:

对我来说,使静态构建有效,它编译为:

g++ -static

It adds the dependent libraries in the build itself.

它在构建本身中添加了依赖库。