2010-04-07 53 views
2

我有点奇怪的问题。我有在C++中的一个项目,基本上是一个第三方DLL像这样的包装:调用加载另一个本机库的本地库时的JNI问题

在MyLibrary
--loads DLL_A
----负载DLL_B

我加载DLL_A与调用LoadLibrary(),包它的几个函数并生成我自己的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

回答

2

其实只有两种方式一个DLL可以加载一个又一个在Windows - 他们要么是明确使用LoadLibrary()做,或者通过链接到的第二个的导入库的第1个DLL是隐式。您应该能够使用Dependency Walker来确定DLL_B是否是DLL_A的依赖关系。如果DLL_B是隐式链接的,则运行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调用,回调机制开始工作?暂时这可能是一个有点丑陋的解决方法。