2017-07-27 73 views
0

我正在使用LWJGL项目,但无法使本机库正常工作。我可以在IDE中运行它,但是当我导出它时,它会崩溃。但这里的问题是,我做了一些代码来提取的Jar本机文件,并到临时文件夹,一旦做到这一点,它会尝试加载本地,但它给这个错误:未找到Java本地文件,当本地文件显然位于java.library.path中时

java.lang.UnsatisfiedLinkError: no jinput-dx8 in java.library.path 
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867) 
    at java.lang.Runtime.loadLibrary0(Runtime.java:870) 
    at java.lang.System.loadLibrary(System.java:1122) 
    at com.test.opengl.engineTester.NativeSupport.loadDLL(NativeSupport.java:46) 
    at com.test.opengl.engineTester.NativeSupport.extract(NativeSupport.java:23) 
    at com.test.opengl.engineTester.MainGameLoop.<clinit>(MainGameLoop.java:21) 

NativeSupport.class:

import java.io.*; 
import java.util.Date; 

public class NativeSupport { 

private static File tempLocation; 



public static void extract() { 
    tempLocation = new File(System.getProperty("java.io.tmpdir") + "/OpenGL_Test_" + new Date().getTime() + "/"); 
    tempLocation.deleteOnExit(); 
    tempLocation.mkdirs(); 
    System.out.println(System.getProperty("java.library.path")); 
    String path = tempLocation.getAbsolutePath()+"\\;"; 
    System.setProperty("java.library.path", path); 
    System.out.println(path); 
    loadDLL("jinput-dx8.dll"); 
    loadDLL("jinput-dx8_64.dll"); 
    loadDLL("jinput-raw.dll"); 
    loadDLL("jinput-raw_64.dll"); 
    loadDLL("lwjgl.dll"); 
    loadDLL("lwjgl64.dll"); 
    loadDLL("OpenAL32.dll"); 
    loadDLL("OpenAL64.dll"); 
} 

private static void loadDLL(String name) { 
    try { 
     System.out.println(name); 
     BufferedReader in = new BufferedReader(new InputStreamReader(Class.class.getResourceAsStream("/"+name))); 
     File fileOut = new File(tempLocation, name); 
     System.out.println(fileOut.getAbsolutePath()); 
     FileWriter out = new FileWriter(fileOut); 

     char[] buffer = new char[1024]; 
     int length; 
     while ((length = in.read(buffer)) > 0) { 
      out.write(buffer, 0, length); 
     } 
     in.close(); 
     out.close(); 
     System.loadLibrary(fileOut.getName().substring(0, fileOut.getName().length()-4)); // Here is where the crash happens 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

public static void clean() { 
} 

} 

萃取方法被称为在从MainGameLoop.class静态呼叫。我已经尝试在主函数中调用它,并且它做了同样的事情。我还确保文件在加载前存在。

我想避免Jar Splice程序。

如果我不清楚任何事情,我会回来的这个问题在大约一天的时间来整理我的问题

感谢您的帮助(我在03:00试图解决这个问题我了),对此,我真的非常感激。

+1

'java.library.path'应包含** **目录包含DLL,DLL本身的不是名称。在'extract()'方法中尝试'tempLocation.getParent()。getAbsolutePath()'。 – Jesper

+0

@Jesper'tempLocation'是DLL的父目录,当在loadDLL(name)方法中加载DLL时,tempLocation是父目录编辑:尝试过了,它仍然不起作用 – SevenDeLeven

回答

0

前一段时间我已经开发了可以帮助你的示例代码。看看这里:

https://github.com/mkowsiak/jnicookbook/tree/master/recipeNo031

你可以发现有几个组件:

  • 库提取(它需要照顾正从jar文件本机代码)
  • HelloWorld类使用任意位置本机文件
  • 照顾所有东西的主类

在你的情况下,我会使用System.load而不是System.loadLibrary。无论如何,你的文件系统上都有这个文件。

与JNI玩得开心。

对于有关JNI更多的样本,看看这里:http://jnicookbook.owsiak.org