我在Java JNI函数上面临不一致的行为。相同的代码在不同的环境中行为不同。我需要你的帮助。
我使用Java JNI和C ++创建了一个函数DLL文件。该函数将字符串作为唯一参数并读取该字符串。我创建了一个测试程序来测试DLL。在测试程序中有一个JNI类,CppWrapper,用于加载DLL并调用DLL中的本机函数。测试成功了。 以下是JNI类
public class CppWrapper {
static{
String jvmBits = System.getProperty("os.arch");
if(jvmBits.equals("x86")){
System.loadLibrary("voice32");
System.out.println(“CppWrapper voice32 loaded”);
}else{
System.loadLibrary("voice64");
System.out.println(“CppWrapper voice64 loaded”);
}
}
native public static int speak(String str);
}
在JNI类中调用本机方法:
String line = toSpeakTextArea.getText();
CppWrapper.speak(line);
我将整个JNI类复制到我正在处理的应用程序中,确切的代码导致了“java.lang.UnsatisfiedLinkError”。 DLL文件已加载但无法找到DLL中的函数。在测试程序中更改JNI类的名称会导致相同的错误。将原始测试程序带到其他PC也会失败。
我将测试程序变成了一个jar文件,并将其作为我的应用程序的依赖项使用它。
现在的情况是,完全与JNI相关的代码只能在特定类名下的特定PC上运行。否则它会失败。你如何解决这个问题?
我使用Netbeans 8.01,JDK1.7.0-67和JRE1.7.0-67。所有项目都是Maven项目。
错误消息来自另一台PC上运行原始测试程序。
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: com.mycompany.speechuserxp.CppWrapper.speak(Ljava/lang/String;)I
at com.mycompany.speechuserxp.CppWrapper.speak(Native Method)
at com.mycompany.speechuserxp.SpeechUserXP.speakButtonActionPerformed(SpeechUserXP.java:143)
at com.mycompany.speechuserxp.SpeechUserXP.access$100(SpeechUserXP.java:15)
at com.mycompany.speechuserxp.SpeechUserXP$2.actionPerformed(SpeechUserXP.java:97)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6516)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3320)
at java.awt.Component.processEvent(Component.java:6281)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4872)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4698)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4698)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:708)
at java.awt.EventQueue$4.run(EventQueue.java:706)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)