java - 调用加载另一个 native 库的 native 库时的 JNI 问题

标签 java dll linker java-native-interface

我遇到了一个奇怪的问题。我有一个 C++ 项目,它基本上是第三方 DLL 的包装器,如下所示:

我的图书馆
--加载 DLL_A
----加载DLL_B

我用 LoadLibrary() 加载 DLL_A,包装它的几个函数并生成我自己的 DLL。我已经在 C++ 项目和 C# 项目中对此进行了测试。两者都做了它们应该做的所有事情:加载 DLL_A,进行几个函数调用,并间接加载 DLL_B。问题是当我为 java 构建 DLL 并通过 JNI 进行调用时。一切正常运行(没有 java.lang.UnsatisfiedLinkError),但是当 DLL_A 加载 DLL_B 时它不起作用。 从调试来看,DLL_B 的加载发生在 DLL_A 中接受回调的函数调用上。当从 Java 调用时,这个函数调用似乎失败了(函数指针很好,实际调用顺利进行),我得到一个奇怪的弹出窗口,说 DLL_B 加载失败,我的程序正在等待一个永远不会发生的回调。我可以很好地显式加载 DLL_B(从 Java 和 C++)并且我已经检查了每条可能的路径、路径变量,并尝试将 dll 放在各处以查看它是否可以在某个地方看起来很有趣。我很确定这不是路径问题。

最终我不知道 DLL_A 是如何加载 DLL_B 的,我也不知道为什么在 C++ 和 C# 中一切正常,但在 Java 中却不行。我完全糊涂了。它仍然可能是我的设置所特有的东西(尽管我已经尽我所能地看了),但我把这个场景扔在那里看看是否有人遇到过类似的问题。

-戴夫

最佳答案

在 Windows 中,一个 DLL 加载另一个 DLL 实际上只有两种方法 - 要么使用 LoadLibrary() 显式执行,要么通过将第一个 DLL 链接到第二个的导入库来隐式执行一。您应该能够使用 Dependency Walker找出 DLL_B 是否是 DLL_A 的依赖项。运行 depwalker 还会显示 DLL_B 是否在路径上,是否隐式链接。

我还会在 DLL_B 上运行 depwalker 以确保 DLL_B 没有令人惊讶的依赖项 - 您看到的问题很可能是由于 DLL_B 无法加载其依赖项之一,而不是 DLL_A 未能找到DLL_B.

IIRC Windows 将扫描 PATH 以查找隐式链接库,因此请检查您对 java 进程的调用是否与该路径一起运行。 LoadLibrary 的文档解释 LoadLibrary 如何扫描 DLL。

你说你设法直接从 Java 加载 DLL_B;当你这样做然后通过 DLL_A 调用时,回调机制是否开始工作?目前这可能是一个有点丑陋的解决方法。

关于java - 调用加载另一个 native 库的 native 库时的 JNI 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2589955/

相关文章:

java - 根据不断变化的 map 对数组进行排序

java - 使用Java Sockets发送ByteArray(Android编程)

java - 为什么方法不返回 true?

c# - 在 App_Web_*.dll 中找到了 index.cshtml 的副本,但正确的源代码与 App_Web_*.dll 中内置的版本不同,

c# - "Could not load file or assembly ' XXX.YYY ' or one of its dependencies. The system cannot find the file specified."

c - 具有同名目标文件的静态库包含同名静态变量

java - 使 List<Boolean> 和 boolean[] 的函数通用

delphi - 用@调用函数

c++ - 需要避免在需要使用链接器脚本 *.ld 文件的静态库中对 `WinMain' 的 undefined reference

gcc - Mac OS 的链接器问题