无法在XP上的Netbeans IDE之外使用JNI加载dll

时间:2014-04-04 20:46:27

标签: dll module java-native-interface 32-bit netbeans-platform

我有一个Netbeans平台应用程序,其中包含一个使用Java Native Interface加载dll的topComponent模块。 dll是在Visual Studio 2012中使用v110_xp工具集创建的,用于与USB设备通信。它确实使用了一些MFC函数,MFC被编译为visual studio的静态库。

在Windows 7 32/64位计算机上运行时,此应用程序或DLL没有问题。在Windows XP计算机上根本不加载dll和topComponent。

为了进一步测试问题,我在XP计算机上安装了Netbeans 7.4,并尝试在调试时加载dll。没有发现问题,所有USB功能都正常工作,topComponent加载没有问题。如果我通过打包作为ZIP发行版从这里发布程序,程序不会加载DLL或topComponent。它只适用于XP 32位计算机,如果我从Netbeans IDE中运行它。

我在dll文件上运行了dependencyWalker,唯一缺少的依赖项是IESHIMS.dll和WER.dll,我已经看到这些是延迟加载的dll,在我的应用程序中永远不需要

有没有人知道为什么这不起作用?

-------------------------更新--------------------- ----

我已经更新了在netbeans中加载dll的方式:

static{
        File dllPath = org.openide.modules.InstalledFileLocator.getDefault().locate("modules/lib/x86", "com.module.foo", false);
        try {
             System.setProperty("java.library.path", dllPath.getAbsolutePath());
             System.setProperty("jna.library.path", dllPath.getAbsolutePath());
             System.setProperty("jni.library.path", dllPath.getAbsolutePath());
             Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
             fieldSysPath.setAccessible(true);
             fieldSysPath.set(null, null);
        } catch (Exception e) {
             throw new RuntimeException(e);
        }
    }

然后我按原样加载dll:

DllInterface INSTANCE = (DllInterface) Native.loadLibrary(
             "My32bitdll" , 
            DllInterface.class);

再次,这只是在Netbeans IDE内部工作得很好....有什么我想念的吗?

------------------------- Update 2 -------------------- -----

我现在也可以通过简单地使用

在Netbeans IDE中实现这一功能
System.loadLibrary("My32bitdll");

它在64位计算机上也没有问题。我通过使用javah修复我的dll文件中的方法名称来实现这一点。

同样,我使用x86 JDK,x86 JRE和32位dll ......仍然不能在netbeans之外工作。

-------------------------更新3 -------------------- -----

我已将此缩小到Netbeans平台应用程序的问题。我可以使用

从标准的java应用程序加载dll
System.load("myDllPath");

我已按照本指南操作:NetBeans Development 7 - Windows 7 64-bit … JNI native calls ... a how to guide 它描述了在Netbeans模块中加载一个DLL,但我仍然无法在Netbeans IDE之外的32位系统上运行它。

2 个答案:

答案 0 :(得分:0)

如果没有至少一条错误消息,很难确切知道发生了什么。假设您的DLL中没有最小的API版本问题,我的猜测是您A)忘记设置java.library.path,而B)将需要二进制文件的其他副本,因为您无法使用32位和64位计算机上的相同dll。 在某些情况下,您可能需要非常努力地避免在64位计算机(也称为WoW64)上运行32位Vm的第三个dll。

当你打包“作为ZIP发行版”时,我会首先弄清楚netbeans正在为你打包的内容。您的DLL文件需要包含在某处,并且在启动应用程序时必须使用-Djava.library.path =指定其位置。有关如何将java指向本机库的更多信息,请参阅有关加载库的this相关帖子。此路径将更改为加载32/64位dll甚至是OS X的dylib和unix的共享对象。您还应该认真考虑构建和打包库的更可靠(独立于IDE)的方法,以避免这些有趣的问题。

答案 1 :(得分:0)

我找到了问题的解决方案。仍然可能需要在netbeans开发团队中需要解决的问题,或者我只是缺少某些东西。

如果我从头开始在32位计算机上创建一个新的netbeans平台应用程序,我能够在使用JNA的system32文件夹中获取依赖于winUSB.dll的dll(在/ release / modules / lib中)。

我从64位计算机启动然后传输到32位计算机的任何Netbeans平台项目都不会正确加载dll依赖项。您可以在32位计算机上调试它们,但它永远不会在Netbeans IDE(7.4)之外工作。