我遇到了一个奇怪的问题。我有一个 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/