JNI problem when calling a native library that loads another native library
I've got a bit of an odd problem. I have a project in C++ that's basically a wrapper for a third party DLL like this:
MyLibrary
--loads DLL_A ----loads DLL_BI load DLL_A with LoadLibrary(), wrap several of its functions and generate my own DLL. I've tested this in a C++ project and a C# project. Both do everything they're supposed to do: load DLL_A, make a couple of function calls, and indirectly load DLL_B. The problem is when I build a DLL for java and make the calls through JNI. Everything runs like it should (no java.lang.UnsatisfiedLinkError), but when it 开发者_如何学Gocomes time for DLL_A to load DLL_B it doesn't work. From debugging, the loading of DLL_B happens on a function call in DLL_A that takes a callback. When called from Java, this function call seems to fail (the function pointer is fine and the actual call goes off without a hitch), and I get an odd pop-up window saying DLL_B failed to load, and my program is left waiting for a callback that never happens. I can explicitly load DLL_B just fine (both from Java and from C++) and I've checked every possible path, path variable, and tried placing the dlls everywhere to see if it could be looking somewhere funny. I'm pretty sure it's not a path problem.
Ultimately I don't know how DLL_A is loading DLL_B and I can't figure out why everything works fine in C++ and C#, but not in Java. I'm absolutely flummoxed. It could still be something specific to my setup (although I've looked as hard as I can look), but I'm throwing this scenario out there to see if anyone has run into a similar problem.
-Dave
There are really only two ways that one DLL can load another one in Windows - either they do it explicitly using LoadLibrary()
or it's implicitly by linking the first DLL against the import library of the second one. You should be able to use Dependency Walker to find out if DLL_B is a dependency of DLL_A or not. Running depwalker will also show you if DLL_B is on the path if it's implicitly linked or not.
I'd also run depwalker on DLL_B to ensure that there are no surprising dependencies for DLL_B - the problem you're seeing might well be caused by DLL_B not being able to load one of its dependencies, not by DLL_A failing to find DLL_B.
IIRC Windows will scan the PATH for implicitly linked libraries, so check if your invocation of your java process plays with the path. The documentation for LoadLibrary
explains how LoadLibrary scans for a DLL.
You said you managed to load DLL_B from Java directly; When you do that and then call through DLL_A, does the callback mechanism start to work? This might be a somewhat ugly workaround for the time being.
精彩评论