我有一个奇怪的问题。我有一个C ++项目,它基本上是第三方DLL的包装器,如下所示:
在MyLibrary
- 加载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中则不行。我绝对陷入困境。它可能仍然是我的设置特有的东西(虽然我看起来像我看起来那么难),但我正在抛出这个场景,看看是否有人遇到过类似的问题。
-Dave
答案 0 :(得分:2)
实际上只有两种方法可以让一个DLL在Windows中加载另一个 - 或者使用LoadLibrary()
明确地执行它,或者通过将第一个DLL与第二个DLL的导入库链接来隐式实现。您应该能够使用Dependency Walker来确定DLL_B是否是DLL_A的依赖项。如果DLL_B位于路径上,则运行的depwalker也会显示它是否隐式链接。
我还会在DLL_B上运行depwalker,以确保DLL_B没有令人惊讶的依赖关系 - 你看到的问题很可能是由于DLL_B无法加载其中一个依赖项,而不是DLL_A无法找到DLL_B。
IIRC Windows将扫描PATH以查找隐式链接库,因此请检查您的java进程调用是否与路径一起使用。 LoadLibrary
的文档解释了LoadLibrary如何扫描DLL。
你说你设法直接从Java加载DLL_B;当你这样做然后通过DLL_A调用时,回调机制是否开始工作?这暂时可能是一种有点丑陋的解决方法。